From b61214db4132593791ed11f628c83cad148a35c0 Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Sun, 16 Sep 2018 15:04:51 -0400 Subject: added timeout to input() --- py/modbuiltins.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/py/modbuiltins.c b/py/modbuiltins.c index fc7ec24c7..8dbcec7e3 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "py/builtin.h" #include "py/stream.h" +#include "py/obj.h" /* For get_int */ #include "supervisor/shared/translate.h" @@ -233,10 +234,41 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hex_obj, mp_builtin_hex); #define mp_hal_readline readline #endif +#include "usb.h" + STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) { - if (n_args == 1) { + if (n_args >= 1) { mp_obj_print(args[0], PRINT_STR); } + if (n_args == 2) + { + if (!mp_obj_is_true(args[1])) + { /* If they pass 0 or False, return immediately if there's no text available */ + if (!usb_bytes_available()) + { + return mp_const_none; + } + } + else if (MP_OBJ_IS_INT(args[1])) + { + /* Timeout has been sent... check for USB input for that # of millis */ + mp_uint_t target = mp_hal_ticks_ms() + mp_obj_get_int(args[1]); + bool bytesAvaliable = false; + + while (mp_hal_ticks_ms() < target) + { + if (usb_bytes_available()) + { + bytesAvaliable = true; + break; + } + } + if (!bytesAvaliable) + return mp_const_none; + } + } + + vstr_t line; vstr_init(&line, 16); int ret = mp_hal_readline(&line, ""); @@ -248,7 +280,7 @@ STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) { } return mp_obj_new_str_from_vstr(&mp_type_str, &line); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 2, mp_builtin_input); #endif -- cgit v1.2.3 From d8c8c5f0058b7184259d537178b16910271d6d5f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Sep 2018 20:26:50 +0700 Subject: remove CFG_HWUART_FOR_SERIAL --- ports/nrf/boards/pca10056/mpconfigboard.h | 3 --- ports/nrf/mphalport.c | 2 +- ports/nrf/supervisor/serial.c | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h index de4545d62..0f3451602 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.h +++ b/ports/nrf/boards/pca10056/mpconfigboard.h @@ -36,9 +36,6 @@ #define PORT_HEAP_SIZE (128 * 1024) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 -// Temp (could be removed) 0: usb cdc (default), 1 : hwuart (jlink) -#define CFG_HWUART_FOR_SERIAL 0 - #define DEFAULT_I2C_BUS_SCL (&pin_P0_27) #define DEFAULT_I2C_BUS_SDA (&pin_P0_26) diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 1e1ebf32e..163ac8d60 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -33,7 +33,7 @@ #if (MICROPY_PY_BLE_NUS == 0) -#if !defined( NRF52840_XXAA) || ( defined(CFG_HWUART_FOR_SERIAL) && CFG_HWUART_FOR_SERIAL == 1 ) +#if !defined( NRF52840_XXAA) int mp_hal_stdin_rx_chr(void) { uint8_t data = 0; diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index da7fe07fd..18a45f10b 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -32,7 +32,7 @@ #include "nrf_gpio.h" #endif -#if !defined( NRF52840_XXAA) || ( defined(CFG_HWUART_FOR_SERIAL) && CFG_HWUART_FOR_SERIAL == 1 ) +#if !defined( NRF52840_XXAA) #define INST_NO 0 -- cgit v1.2.3 From 1df3bcf39227f6a71dbed5c2016e4603b70a92ef Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Sep 2018 14:40:37 +0700 Subject: add board.UART() function --- ports/nrf/Makefile | 1 + ports/nrf/boards/pca10056/mpconfigboard.h | 9 ++------- ports/nrf/boards/pca10056/pins.c | 2 ++ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 0e9d224be..d48b20fd3 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -100,6 +100,7 @@ SRC_C += \ internal_flash.c \ mphalport.c \ tick.c \ + board_busses.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h index 0f3451602..5aa2191f7 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.h +++ b/ports/nrf/boards/pca10056/mpconfigboard.h @@ -28,11 +28,6 @@ #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "nRF52840-DK" -// See legend on bottom of board -#define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8) -#define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6) -#define MICROPY_HW_UART_HWFC (0) - #define PORT_HEAP_SIZE (128 * 1024) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 @@ -43,5 +38,5 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) #define DEFAULT_SPI_BUS_MISO (&pin_P1_14) -#define DEFAULT_UART_BUS_RX (&pin_P1_01) -#define DEFAULT_UART_BUS_TX (&pin_P1_02) +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/pca10056/pins.c b/ports/nrf/boards/pca10056/pins.c index 1c208f89b..a57c9d1c9 100644 --- a/ports/nrf/boards/pca10056/pins.c +++ b/ports/nrf/boards/pca10056/pins.c @@ -124,6 +124,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); -- cgit v1.2.3 From c5593ec074236a050abb627f7b637e5409e4d3c0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Sep 2018 17:59:15 +0700 Subject: got uart tx work --- ports/nrf/boards/pca10056/mpconfigboard.h | 4 +- ports/nrf/common-hal/busio/UART.c | 194 ++++++++++++++++++++++++++++-- ports/nrf/common-hal/busio/UART.h | 5 +- 3 files changed, 191 insertions(+), 12 deletions(-) diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h index 5aa2191f7..00a73005c 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.h +++ b/ports/nrf/boards/pca10056/mpconfigboard.h @@ -38,5 +38,5 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) #define DEFAULT_SPI_BUS_MISO (&pin_P1_14) -#define DEFAULT_UART_BUS_RX (&pin_P0_08) -#define DEFAULT_UART_BUS_TX (&pin_P0_06) +#define DEFAULT_UART_BUS_RX (&pin_P1_01) +#define DEFAULT_UART_BUS_TX (&pin_P1_02) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index f05949e15..bcf335d65 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -35,54 +35,234 @@ #include "supervisor/shared/translate.h" #include "tick.h" +#include "nrfx_uart.h" -void common_hal_busio_uart_construct(busio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, - uint8_t receiver_buffer_size) { +static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); + +// expression to examine, and return value in case of failing +#define _VERIFY_ERR(_exp, _ret) \ + do {\ + uint32_t _err = (_exp);\ + if (NRFX_SUCCESS != _err ) {\ + mp_raise_msg_varg(&mp_type_AssertionError, translate("error = 0x%08lX "), _err);\ + return _ret;\ + }\ + }while(0) + +static uint32_t get_nrf_baud (uint32_t baudrate); + + +static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) { + busio_uart_obj_t* self = (busio_uart_obj_t*) context; + + switch ( event->type ) { + case NRFX_UART_EVT_TX_DONE: + case NRFX_UART_EVT_RX_DONE: + self->xferred_bytes = event->data.rxtx.bytes; + break; + + default: + self->xferred_bytes = -(event->data.error.rxtx.bytes); + break; + } +} + + +void common_hal_busio_uart_construct (busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, + uint8_t receiver_buffer_size) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +#else + if ( parity == PARITY_ODD ) { + mp_raise_ValueError(translate("busio.UART odd parity is not supported")); + } + + if ( (tx == mp_const_none) || (rx == mp_const_none) ) { + mp_raise_ValueError(translate("Invalid pins")); + } + + if ( receiver_buffer_size == 0 ) { + mp_raise_ValueError(translate("Invalid buffer size")); + } + + nrfx_uart_config_t config = { + .pseltxd = tx->number, + .pseltxd = rx->number, + .pselcts = NRF_UART_PSEL_DISCONNECTED, + .pselrts = NRF_UART_PSEL_DISCONNECTED, + .p_context = self, + .hwfc = NRF_UART_HWFC_DISABLED, + .parity = (parity == PARITY_NONE) ? NRF_UART_PARITY_EXCLUDED : NRF_UART_PARITY_INCLUDED, + .baudrate = get_nrf_baud(baudrate), + .interrupt_priority = 7 + }; + + nrfx_uart_uninit(&_uart); + _VERIFY_ERR(nrfx_uart_init(&_uart, &config, uart_callback_irq),); + nrfx_uart_rx_enable(&_uart); + + self->buffer_length = receiver_buffer_size; + self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, false); + if ( self->buffer == NULL ) { + nrfx_uart_uninit(&_uart); + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + } + + self->baudrate = baudrate; + self->timeout_ms = timeout; +#endif } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +#else + return (nrf_uart_rx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED) || + (nrf_uart_tx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED); +#endif } void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); - if (common_hal_busio_uart_deinited(self)) { - return; +#else + if ( !common_hal_busio_uart_deinited(self) ) { + nrfx_uart_uninit(&_uart); + gc_free(self->buffer); } - // Do deinit; +#endif } // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return 0; +#else + + + + if ( (*errcode) == NRFX_SUCCESS ) { + (*errcode) = 0; + } + + return 0; +#endif } // Write characters. size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return 0; +#else + self->xferred_bytes = 0; + + (*errcode) = nrfx_uart_tx(&_uart, data, len); + _VERIFY_ERR(*errcode, MP_STREAM_ERROR); + (*errcode) = 0; + + uint64_t start_ticks = ticks_ms; + while ( (0 == self->xferred_bytes) && (ticks_ms - start_ticks < self->timeout_ms) ) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + if ( self->xferred_bytes <= 0 ) { + mp_raise_msg_varg(&mp_type_AssertionError, translate("failed")); + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + + return len; +#endif } uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +#endif return self->baudrate; } void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +#else self->baudrate = baudrate; + nrf_uart_baudrate_set(_uart.p_reg, get_nrf_baud(baudrate)); +#endif } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +#else + +#endif return 0; } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { +#ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return false; +#else + return !nrfx_uart_tx_in_progress(&_uart); +#endif +} + +static uint32_t get_nrf_baud (uint32_t baudrate) +{ + if ( baudrate <= 1200 ) { + return NRF_UART_BAUDRATE_1200; + } + else if ( baudrate <= 2400 ) { + return NRF_UART_BAUDRATE_2400; + } + else if ( baudrate <= 4800 ) { + return NRF_UART_BAUDRATE_4800; + } + else if ( baudrate <= 9600 ) { + return NRF_UART_BAUDRATE_9600; + } + else if ( baudrate <= 14400 ) { + return NRF_UART_BAUDRATE_14400; + } + else if ( baudrate <= 19200 ) { + return NRF_UART_BAUDRATE_19200; + } + else if ( baudrate <= 28800 ) { + return NRF_UART_BAUDRATE_28800; + } + else if ( baudrate <= 38400 ) { + return NRF_UART_BAUDRATE_38400; + } + else if ( baudrate <= 57600 ) { + return NRF_UART_BAUDRATE_57600; + } + else if ( baudrate <= 76800 ) { + return NRF_UART_BAUDRATE_76800; + } + else if ( baudrate <= 115200 ) { + return NRF_UART_BAUDRATE_115200; + } + else if ( baudrate <= 230400 ) { + return NRF_UART_BAUDRATE_230400; + } + else if ( baudrate <= 250000 ) { + return NRF_UART_BAUDRATE_250000; + } + else if ( baudrate <= 460800 ) { + return NRF_UART_BAUDRATE_460800; + } + else if ( baudrate <= 921600 ) { + return NRF_UART_BAUDRATE_921600; + } + else { + return NRF_UART_BAUDRATE_1000000; + } } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 7c0493e37..ec3737357 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -33,9 +33,6 @@ typedef struct { mp_obj_base_t base; - uint8_t rx_pin; - uint8_t tx_pin; - uint8_t character_bits; bool rx_error; uint32_t baudrate; uint32_t timeout_ms; @@ -45,6 +42,8 @@ typedef struct { uint32_t buffer_size; uint32_t buffer_length; uint8_t* buffer; + + volatile int32_t xferred_bytes; } busio_uart_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H -- cgit v1.2.3 From 9c25306877b3bd381730dfbc82533fc2b683fff3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 20 Sep 2018 01:07:45 +0700 Subject: uart rx got some issue with irq --- ports/nrf/common-hal/busio/UART.c | 99 ++++++++++++++++++++++++++++++++------- ports/nrf/common-hal/busio/UART.h | 13 ++--- 2 files changed, 86 insertions(+), 26 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index bcf335d65..2c6246f60 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -36,32 +36,49 @@ #include "tick.h" #include "nrfx_uart.h" +#include static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); // expression to examine, and return value in case of failing -#define _VERIFY_ERR(_exp, _ret) \ +#define _VERIFY_ERR(_exp) \ do {\ uint32_t _err = (_exp);\ if (NRFX_SUCCESS != _err ) {\ mp_raise_msg_varg(&mp_type_AssertionError, translate("error = 0x%08lX "), _err);\ - return _ret;\ }\ }while(0) static uint32_t get_nrf_baud (uint32_t baudrate); +static uint32_t rd_error = 0; static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { case NRFX_UART_EVT_TX_DONE: - case NRFX_UART_EVT_RX_DONE: self->xferred_bytes = event->data.rxtx.bytes; break; + case NRFX_UART_EVT_RX_DONE: + // mp_raise_msg_varg(&mp_type_AssertionError, translate("error = 0x%08lX "), event->data.rxtx.bytes); +// for ( int i = 0; i < event->data.rxtx.bytes; i++ ) { +// if ( 0 > ringbuf_put(&self->rx_rbuf, self->rx_xact_buf[i]) ) { +// // buffer is full, overwrite old data +// ringbuf_get(&self->rx_rbuf); +// ringbuf_put(&self->rx_rbuf, self->rx_xact_buf[i]); +// } +// } +// +// nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf)); +// nrfx_uart_rx_enable(&_uart); + + self->rx_count = event->data.rxtx.bytes; + break; + default: + rd_error = event->data.error.error_mask; self->xferred_bytes = -(event->data.error.rxtx.bytes); break; } @@ -95,23 +112,26 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, .p_context = self, .hwfc = NRF_UART_HWFC_DISABLED, .parity = (parity == PARITY_NONE) ? NRF_UART_PARITY_EXCLUDED : NRF_UART_PARITY_INCLUDED, - .baudrate = get_nrf_baud(baudrate), + .baudrate = NRF_UART_BAUDRATE_9600, // get_nrf_baud(baudrate), .interrupt_priority = 7 }; nrfx_uart_uninit(&_uart); - _VERIFY_ERR(nrfx_uart_init(&_uart, &config, uart_callback_irq),); - nrfx_uart_rx_enable(&_uart); + _VERIFY_ERR(nrfx_uart_init(&_uart, &config, uart_callback_irq)); - self->buffer_length = receiver_buffer_size; - self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, false); - if ( self->buffer == NULL ) { + // Init ring buffer for rx + self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); + if ( !self->buffer ) { nrfx_uart_uninit(&_uart); mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); } + self->bufsize = receiver_buffer_size; self->baudrate = baudrate; self->timeout_ms = timeout; + + _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); + nrfx_uart_rx_enable(&_uart); #endif } @@ -130,7 +150,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { #else if ( !common_hal_busio_uart_deinited(self) ) { nrfx_uart_uninit(&_uart); - gc_free(self->buffer); +// gc_free(self->buffer); } #endif } @@ -142,13 +162,51 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t return 0; #else - - - if ( (*errcode) == NRFX_SUCCESS ) { - (*errcode) = 0; + if ( rd_error ) { + printf("error = 0x%08lX\n", rd_error); + rd_error = 0; } - return 0; + size_t remain = len; +// uint64_t start_ticks = ticks_ms; +// while ( remain && (ticks_ms - start_ticks < self->timeout_ms) ) { +// if ( self->rx_count ) { +// size_t cnt = MIN(self->rx_count, remain); +// memcpy(data, self->buffer, cnt); +// data += cnt; +// remain -= cnt; +// +// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); +// nrfx_uart_rx_enable(&_uart); +// } +//#if 0 +// uint32_t received = common_hal_busio_uart_rx_characters_available(self); +// +// // enough bytes received or ringbuffer is full +// if ( (received >= remain) || (received == self->rx_rbuf.size - 1) ) { +// nrfx_uart_rx_abort(&_uart); +// +// while ( !_ringbuf_is_empty(&self->rx_rbuf) ) { +// *data++ = ringbuf_get(&self->rx_rbuf); +// remain--; +// } +// +// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); +// nrfx_uart_rx_enable(&_uart); +// } +//#endif +// +//#ifdef MICROPY_VM_HOOK_LOOP +// MICROPY_VM_HOOK_LOOP +//#endif +// } + + printf("rx count = 0x%08lX\n", self->rx_count); + + _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); + nrfx_uart_rx_enable(&_uart); + + return len - remain; #endif } @@ -161,7 +219,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, self->xferred_bytes = 0; (*errcode) = nrfx_uart_tx(&_uart, data, len); - _VERIFY_ERR(*errcode, MP_STREAM_ERROR); + _VERIFY_ERR(*errcode); (*errcode) = 0; uint64_t start_ticks = ticks_ms; @@ -201,9 +259,14 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - +// int count = ((volatile uint16_t) self->rx_rbuf.iput) - ((volatile uint16_t) self->rx_rbuf.iget); +// if ( count < 0 ) { +// count += self->rx_rbuf.size; +// } +// +// return count; + return self->rx_count; #endif - return 0; } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index ec3737357..8018a9316 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -30,20 +30,17 @@ #include "common-hal/microcontroller/Pin.h" #include "py/obj.h" +#include "py/ringbuf.h" typedef struct { mp_obj_base_t base; - bool rx_error; uint32_t baudrate; uint32_t timeout_ms; - // Index of the oldest received character. - uint32_t buffer_start; - // Index of the next available spot to store a character. - uint32_t buffer_size; - uint32_t buffer_length; - uint8_t* buffer; - volatile int32_t xferred_bytes; + + uint8_t* buffer; + uint32_t bufsize; + volatile uint32_t rx_count; } busio_uart_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H -- cgit v1.2.3 From fe1a2978893555209b26939062cb163208697e2f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Sep 2018 01:27:52 +0700 Subject: still have issue with initial uart rx --- ports/nrf/common-hal/busio/UART.c | 91 ++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 2c6246f60..79b49464d 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -51,6 +51,12 @@ static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); static uint32_t get_nrf_baud (uint32_t baudrate); +static inline bool is_receiving (busio_uart_obj_t *self) { + (void) self; + return nrf_uart_int_enable_check(_uart.p_reg, NRF_UART_INT_MASK_RXDRDY); +} + + static uint32_t rd_error = 0; static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) { @@ -62,24 +68,17 @@ static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) break; case NRFX_UART_EVT_RX_DONE: - // mp_raise_msg_varg(&mp_type_AssertionError, translate("error = 0x%08lX "), event->data.rxtx.bytes); -// for ( int i = 0; i < event->data.rxtx.bytes; i++ ) { -// if ( 0 > ringbuf_put(&self->rx_rbuf, self->rx_xact_buf[i]) ) { -// // buffer is full, overwrite old data -// ringbuf_get(&self->rx_rbuf); -// ringbuf_put(&self->rx_rbuf, self->rx_xact_buf[i]); -// } -// } -// -// nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf)); -// nrfx_uart_rx_enable(&_uart); - - self->rx_count = event->data.rxtx.bytes; + self->rx_count += event->data.rxtx.bytes; break; default: rd_error = event->data.error.error_mask; - self->xferred_bytes = -(event->data.error.rxtx.bytes); + + // Walkaround for first 2 error after nrfx_uart_rx_enable() + // queue RX if there is no data and no on-going rx +// if ( !self->rx_count && !is_receiving(self) ) { +// nrfx_uart_rx(&_uart, self->buffer, self->bufsize); +// } break; } } @@ -92,10 +91,6 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - if ( parity == PARITY_ODD ) { - mp_raise_ValueError(translate("busio.UART odd parity is not supported")); - } - if ( (tx == mp_const_none) || (rx == mp_const_none) ) { mp_raise_ValueError(translate("Invalid pins")); } @@ -104,6 +99,10 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, mp_raise_ValueError(translate("Invalid buffer size")); } + if ( parity == PARITY_ODD ) { + mp_raise_ValueError(translate("busio.UART odd parity is not supported")); + } + nrfx_uart_config_t config = { .pseltxd = tx->number, .pseltxd = rx->number, @@ -112,14 +111,14 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, .p_context = self, .hwfc = NRF_UART_HWFC_DISABLED, .parity = (parity == PARITY_NONE) ? NRF_UART_PARITY_EXCLUDED : NRF_UART_PARITY_INCLUDED, - .baudrate = NRF_UART_BAUDRATE_9600, // get_nrf_baud(baudrate), + .baudrate = get_nrf_baud(baudrate), .interrupt_priority = 7 }; nrfx_uart_uninit(&_uart); _VERIFY_ERR(nrfx_uart_init(&_uart, &config, uart_callback_irq)); - // Init ring buffer for rx + // Init buffer for rx self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); if ( !self->buffer ) { nrfx_uart_uninit(&_uart); @@ -130,8 +129,11 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, self->baudrate = baudrate; self->timeout_ms = timeout; - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); nrfx_uart_rx_enable(&_uart); + + // Somehow the first 2 calls of nrfx_uart_rx will (probably) cause Frame, then Break error + // effectively cancel the rx preps --> Walkaround: keep calling nrfx_uart_rx in error handler if needed + _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); #endif } @@ -167,44 +169,41 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t rd_error = 0; } + printf("rx count = 0x%08lX\n", self->rx_count); + size_t remain = len; + // uint64_t start_ticks = ticks_ms; +// // while ( remain && (ticks_ms - start_ticks < self->timeout_ms) ) { -// if ( self->rx_count ) { -// size_t cnt = MIN(self->rx_count, remain); +// // have enough or buffer is full +// if ( (self->rx_count >= remain) || (self->rx_count == self->bufsize) ) { +// if ( is_receiving(self) ) { +// nrfx_uart_rx_abort(&_uart); +// } +// +// const size_t cnt = MIN(self->rx_count, remain); +// // memcpy(data, self->buffer, cnt); // data += cnt; // remain -= cnt; // -// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); -// nrfx_uart_rx_enable(&_uart); -// } -//#if 0 -// uint32_t received = common_hal_busio_uart_rx_characters_available(self); -// -// // enough bytes received or ringbuffer is full -// if ( (received >= remain) || (received == self->rx_rbuf.size - 1) ) { -// nrfx_uart_rx_abort(&_uart); +// self->rx_count -= cnt; // -// while ( !_ringbuf_is_empty(&self->rx_rbuf) ) { -// *data++ = ringbuf_get(&self->rx_rbuf); -// remain--; +// // shift buffer if we didn't consume it all +// if ( self->rx_count ) { +// memmove(self->buffer, self->buffer + cnt, self->rx_count); // } -// -// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); -// nrfx_uart_rx_enable(&_uart); // } -//#endif +// +//// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); // //#ifdef MICROPY_VM_HOOK_LOOP // MICROPY_VM_HOOK_LOOP //#endif // } - printf("rx count = 0x%08lX\n", self->rx_count); - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); - nrfx_uart_rx_enable(&_uart); return len - remain; #endif @@ -259,13 +258,7 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else -// int count = ((volatile uint16_t) self->rx_rbuf.iput) - ((volatile uint16_t) self->rx_rbuf.iget); -// if ( count < 0 ) { -// count += self->rx_rbuf.size; -// } -// -// return count; - return self->rx_count; +return self->rx_count + (nrfx_uart_rx_ready(&_uart) ? 1 : 0); #endif } -- cgit v1.2.3 From dddc437ea7fc98cb3c1e6e9e2bc5e16dfa690769 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Sep 2018 03:48:13 +0700 Subject: got rx working finally --- ports/nrf/common-hal/busio/UART.c | 122 +++++++++++++++++++++----------------- ports/nrf/common-hal/busio/UART.h | 1 + 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 79b49464d..9cb7f8dc1 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -36,7 +36,7 @@ #include "tick.h" #include "nrfx_uart.h" -#include +#include static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); @@ -51,14 +51,6 @@ static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); static uint32_t get_nrf_baud (uint32_t baudrate); -static inline bool is_receiving (busio_uart_obj_t *self) { - (void) self; - return nrf_uart_int_enable_check(_uart.p_reg, NRF_UART_INT_MASK_RXDRDY); -} - - -static uint32_t rd_error = 0; - static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; @@ -69,16 +61,10 @@ static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) case NRFX_UART_EVT_RX_DONE: self->rx_count += event->data.rxtx.bytes; + self->receiving = false; break; default: - rd_error = event->data.error.error_mask; - - // Walkaround for first 2 error after nrfx_uart_rx_enable() - // queue RX if there is no data and no on-going rx -// if ( !self->rx_count && !is_receiving(self) ) { -// nrfx_uart_rx(&_uart, self->buffer, self->bufsize); -// } break; } } @@ -105,7 +91,7 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, nrfx_uart_config_t config = { .pseltxd = tx->number, - .pseltxd = rx->number, + .pselrxd = rx->number, .pselcts = NRF_UART_PSEL_DISCONNECTED, .pselrts = NRF_UART_PSEL_DISCONNECTED, .p_context = self, @@ -131,8 +117,7 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, nrfx_uart_rx_enable(&_uart); - // Somehow the first 2 calls of nrfx_uart_rx will (probably) cause Frame, then Break error - // effectively cancel the rx preps --> Walkaround: keep calling nrfx_uart_rx in error handler if needed + self->receiving = true; _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); #endif } @@ -157,6 +142,21 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { #endif } +static size_t get_rx_data (busio_uart_obj_t *self, uint8_t *data, size_t len) { + // up to max received + const size_t cnt = MIN(self->rx_count, len); + + memcpy(data, self->buffer, cnt); + self->rx_count -= cnt; + + // shift buffer if we didn't consume it all + if ( self->rx_count ) { + memmove(self->buffer, self->buffer + cnt, self->rx_count); + } + + return cnt; +} + // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { #ifndef NRF52840_XXAA @@ -164,46 +164,56 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t return 0; #else - if ( rd_error ) { - printf("error = 0x%08lX\n", rd_error); - rd_error = 0; + size_t remain = len; + uint64_t start_ticks = ticks_ms; + + // nrfx_uart doesn't provide API to check number of bytes received so far for the on going reception. + // we have to abort the current transfer to get rx_count updated !!! + if ( self->receiving ) { + nrfx_uart_rx_abort(&_uart); + while ( self->receiving ) { + } } - printf("rx count = 0x%08lX\n", self->rx_count); + size_t cnt = get_rx_data(self, data, remain); + data += cnt; + remain -= cnt; - size_t remain = len; + if ( self->timeout_ms ) { + do { + if ( remain == 0 ) { + break; + } -// uint64_t start_ticks = ticks_ms; -// -// while ( remain && (ticks_ms - start_ticks < self->timeout_ms) ) { -// // have enough or buffer is full -// if ( (self->rx_count >= remain) || (self->rx_count == self->bufsize) ) { -// if ( is_receiving(self) ) { -// nrfx_uart_rx_abort(&_uart); -// } -// -// const size_t cnt = MIN(self->rx_count, remain); -// -// memcpy(data, self->buffer, cnt); -// data += cnt; -// remain -= cnt; -// -// self->rx_count -= cnt; -// -// // shift buffer if we didn't consume it all -// if ( self->rx_count ) { -// memmove(self->buffer, self->buffer + cnt, self->rx_count); -// } -// } -// -//// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->rx_xact_buf, sizeof(self->rx_xact_buf))); -// -//#ifdef MICROPY_VM_HOOK_LOOP -// MICROPY_VM_HOOK_LOOP -//#endif -// } + // no data, no transfer, start with only 1 byte each so that we could know when data is available + if ( !self->rx_count && !self->receiving ) { + self->receiving = true; + _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, 1)); + } - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); + if ( self->rx_count ) { + *data++ = self->buffer[0]; + remain--; + self->rx_count--; + } + +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + + } while ( ticks_ms - start_ticks < self->timeout_ms ); + } + + // abort oon-going 1 byte transfer + if ( self->receiving ) { + nrfx_uart_rx_abort(&_uart); + while ( self->receiving ) { + } + } + + // queue full buffer transfer + self->receiving = true; + _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer + self->rx_count, self->bufsize - self->rx_count)); return len - remain; #endif @@ -226,6 +236,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif + // break if zero timeout + if ( self->timeout_ms == 0 ) { + break; + } } if ( self->xferred_bytes <= 0 ) { diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 8018a9316..5cd0bae41 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -41,6 +41,7 @@ typedef struct { uint8_t* buffer; uint32_t bufsize; volatile uint32_t rx_count; + volatile bool receiving; } busio_uart_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H -- cgit v1.2.3 From 816ff052534224967283aa657ba63b007c286cbe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Sep 2018 03:53:35 +0700 Subject: clean up --- ports/nrf/common-hal/busio/UART.c | 13 ++++--------- ports/nrf/common-hal/busio/UART.h | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 9cb7f8dc1..ec3d55fef 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -56,7 +56,7 @@ static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) switch ( event->type ) { case NRFX_UART_EVT_TX_DONE: - self->xferred_bytes = event->data.rxtx.bytes; + self->tx_count = event->data.rxtx.bytes; break; case NRFX_UART_EVT_RX_DONE: @@ -225,25 +225,20 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return 0; #else - self->xferred_bytes = 0; + self->tx_count = 0; (*errcode) = nrfx_uart_tx(&_uart, data, len); _VERIFY_ERR(*errcode); (*errcode) = 0; uint64_t start_ticks = ticks_ms; - while ( (0 == self->xferred_bytes) && (ticks_ms - start_ticks < self->timeout_ms) ) { + while ( (0 == self->tx_count) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif - // break if zero timeout - if ( self->timeout_ms == 0 ) { - break; - } } - if ( self->xferred_bytes <= 0 ) { - mp_raise_msg_varg(&mp_type_AssertionError, translate("failed")); + if ( self->tx_count <= 0 ) { *errcode = MP_EAGAIN; return MP_STREAM_ERROR; } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 5cd0bae41..3cb9e5fda 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -36,7 +36,7 @@ typedef struct { mp_obj_base_t base; uint32_t baudrate; uint32_t timeout_ms; - volatile int32_t xferred_bytes; + volatile int32_t tx_count; uint8_t* buffer; uint32_t bufsize; -- cgit v1.2.3 From fdd3e91753a74dc779fbb001abaf6b2d0761ec42 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Sep 2018 14:37:28 +0700 Subject: changing to nrf uarte, tx works fine --- ports/nrf/Makefile | 2 +- ports/nrf/common-hal/busio/UART.c | 48 +++++++++++++++++++-------------------- ports/nrf/common-hal/busio/UART.h | 1 - ports/nrf/nrfx_config.h | 5 ++++ 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index d48b20fd3..93ca78376 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -91,7 +91,7 @@ SRC_NRFX = $(addprefix nrfx/,\ drivers/src/nrfx_power.c \ drivers/src/nrfx_spim.c \ drivers/src/nrfx_twim.c \ - drivers/src/nrfx_uart.c \ + drivers/src/nrfx_uarte.c \ ) SRC_C += \ diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 260b958ea..b9b182247 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -35,10 +35,10 @@ #include "supervisor/shared/translate.h" #include "tick.h" -#include "nrfx_uart.h" +#include "nrfx_uarte.h" #include -static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); +static nrfx_uarte_t _uart = NRFX_UARTE_INSTANCE(0); // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ @@ -51,12 +51,11 @@ static nrfx_uart_t _uart = NRFX_UART_INSTANCE(0); static uint32_t get_nrf_baud (uint32_t baudrate); -static void uart_callback_irq (const nrfx_uart_event_t * event, void * context) { +static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { case NRFX_UART_EVT_TX_DONE: - self->tx_count = event->data.rxtx.bytes; break; case NRFX_UART_EVT_RX_DONE: @@ -89,7 +88,7 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, mp_raise_ValueError(translate("busio.UART odd parity is not supported")); } - nrfx_uart_config_t config = { + nrfx_uarte_config_t config = { .pseltxd = tx->number, .pselrxd = rx->number, .pselcts = NRF_UART_PSEL_DISCONNECTED, @@ -101,13 +100,13 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, .interrupt_priority = 7 }; - nrfx_uart_uninit(&_uart); - _VERIFY_ERR(nrfx_uart_init(&_uart, &config, uart_callback_irq)); + nrfx_uarte_uninit(&_uart); + _VERIFY_ERR(nrfx_uarte_init(&_uart, &config, uart_callback_irq)); // Init buffer for rx self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); if ( !self->buffer ) { - nrfx_uart_uninit(&_uart); + nrfx_uarte_uninit(&_uart); mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); } self->bufsize = receiver_buffer_size; @@ -115,10 +114,10 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, self->baudrate = baudrate; self->timeout_ms = timeout; - nrfx_uart_rx_enable(&_uart); - - self->receiving = true; - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); +// nrfx_uart_rx_enable(&_uart); +// +// self->receiving = true; +// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); #endif } @@ -136,8 +135,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else if ( !common_hal_busio_uart_deinited(self) ) { - nrfx_uart_uninit(&_uart); -// gc_free(self->buffer); + nrfx_uarte_uninit(&_uart); + gc_free(self->buffer); } #endif } @@ -165,6 +164,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t #else size_t remain = len; +#if 0 uint64_t start_ticks = ticks_ms; // nrfx_uart doesn't provide API to check number of bytes received so far for the on going reception. @@ -214,8 +214,9 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // queue full buffer transfer self->receiving = true; _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer + self->rx_count, self->bufsize - self->rx_count)); - +#endif return len - remain; + #endif } @@ -225,24 +226,19 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return 0; #else - self->tx_count = 0; + if ( len == 0 ) return 0; - (*errcode) = nrfx_uart_tx(&_uart, data, len); + (*errcode) = nrfx_uarte_tx(&_uart, data, len); _VERIFY_ERR(*errcode); (*errcode) = 0; uint64_t start_ticks = ticks_ms; - while ( (0 == self->tx_count) && (ticks_ms - start_ticks < self->timeout_ms) ) { + while ( nrfx_uarte_tx_in_progress(&_uart) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif } - if ( self->tx_count <= 0 ) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - return len; #endif } @@ -267,7 +263,8 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else -return self->rx_count + (nrfx_uart_rx_ready(&_uart) ? 1 : 0); +//return self->rx_count + (nrfx_uart_rx_ready(&_uart) ? 1 : 0); + return false; #endif } @@ -280,7 +277,8 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return false; #else - return !nrfx_uart_tx_in_progress(&_uart); +// return !nrfx_uart_tx_in_progress(&_uart); + return true; #endif } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 3cb9e5fda..7c693bf6c 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -36,7 +36,6 @@ typedef struct { mp_obj_base_t base; uint32_t baudrate; uint32_t timeout_ms; - volatile int32_t tx_count; uint8_t* buffer; uint32_t bufsize; diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index cc4d19327..0ccfecb21 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -45,8 +45,13 @@ #define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 // UART +#if 0 #define NRFX_UART_ENABLED 1 #define NRFX_UART0_ENABLED 1 +#else +#define NRFX_UARTE_ENABLED 1 +#define NRFX_UARTE0_ENABLED 1 +#endif #define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_UART_DEFAULT_CONFIG_HWFC NRF_UART_HWFC_DISABLED -- cgit v1.2.3 From 7bbd449f067ea4604059d1a8c12e8a8333a528bf Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Sep 2018 15:54:32 +0700 Subject: uarte rx work fine --- ports/nrf/common-hal/busio/UART.c | 97 +++++++++++---------------------------- ports/nrf/common-hal/busio/UART.h | 3 +- 2 files changed, 28 insertions(+), 72 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index b9b182247..6f4e0af8e 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -59,8 +59,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) break; case NRFX_UART_EVT_RX_DONE: - self->rx_count += event->data.rxtx.bytes; - self->receiving = false; + self->rx_count = event->data.rxtx.bytes; break; default: @@ -113,11 +112,6 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, self->baudrate = baudrate; self->timeout_ms = timeout; - -// nrfx_uart_rx_enable(&_uart); -// -// self->receiving = true; -// _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, self->bufsize)); #endif } @@ -125,8 +119,8 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - return (nrf_uart_rx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED) || - (nrf_uart_tx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED); + return (nrf_uarte_rx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED) || + (nrf_uarte_tx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED); #endif } @@ -141,21 +135,6 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { #endif } -static size_t get_rx_data (busio_uart_obj_t *self, uint8_t *data, size_t len) { - // up to max received - const size_t cnt = MIN(self->rx_count, len); - - memcpy(data, self->buffer, cnt); - self->rx_count -= cnt; - - // shift buffer if we didn't consume it all - if ( self->rx_count ) { - memmove(self->buffer, self->buffer + cnt, self->rx_count); - } - - return cnt; -} - // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { #ifndef NRF52840_XXAA @@ -164,59 +143,35 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t #else size_t remain = len; -#if 0 uint64_t start_ticks = ticks_ms; - // nrfx_uart doesn't provide API to check number of bytes received so far for the on going reception. - // we have to abort the current transfer to get rx_count updated !!! - if ( self->receiving ) { - nrfx_uart_rx_abort(&_uart); - while ( self->receiving ) { - } - } - - size_t cnt = get_rx_data(self, data, remain); - data += cnt; - remain -= cnt; + while ( remain && (ticks_ms - start_ticks < self->timeout_ms) ) { + const size_t cnt = MIN(self->bufsize, len); - if ( self->timeout_ms ) { - do { - if ( remain == 0 ) { - break; - } - - // no data, no transfer, start with only 1 byte each so that we could know when data is available - if ( !self->rx_count && !self->receiving ) { - self->receiving = true; - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer, 1)); - } - - if ( self->rx_count ) { - *data++ = self->buffer[0]; - remain--; - self->rx_count--; - } + self->rx_count = -1; + _VERIFY_ERR(nrfx_uarte_rx(&_uart, self->buffer, cnt)); + while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif + } - } while ( ticks_ms - start_ticks < self->timeout_ms ); - } + // Time up, abort rx use received so far + if ( self->rx_count == -1 ) { + nrfx_uarte_rx_abort(&_uart); + while ( self->rx_count == -1 ) { + } + } - // abort oon-going 1 byte transfer - if ( self->receiving ) { - nrfx_uart_rx_abort(&_uart); - while ( self->receiving ) { + if ( self->rx_count > 0 ) { + memcpy(data, self->buffer, self->rx_count); + data += self->rx_count; + remain -= self->rx_count; } } - - // queue full buffer transfer - self->receiving = true; - _VERIFY_ERR(nrfx_uart_rx(&_uart, self->buffer + self->rx_count, self->bufsize - self->rx_count)); -#endif + return len - remain; - #endif } @@ -228,6 +183,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, #else if ( len == 0 ) return 0; + if ( !nrfx_uarte_tx_in_progress(&_uart) ) { + nrfx_uarte_tx_abort(&_uart); + } + (*errcode) = nrfx_uarte_tx(&_uart, data, len); _VERIFY_ERR(*errcode); (*errcode) = 0; @@ -255,7 +214,7 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else self->baudrate = baudrate; - nrf_uart_baudrate_set(_uart.p_reg, get_nrf_baud(baudrate)); + nrf_uarte_baudrate_set(_uart.p_reg, get_nrf_baud(baudrate)); #endif } @@ -263,8 +222,7 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else -//return self->rx_count + (nrfx_uart_rx_ready(&_uart) ? 1 : 0); - return false; + return 1; // nrf_uart_event_check(_uart.p_reg, NRF_UART_EVENT_RXDRDY) ? 1 : 0; #endif } @@ -277,8 +235,7 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return false; #else -// return !nrfx_uart_tx_in_progress(&_uart); - return true; + return !nrfx_uarte_tx_in_progress(&_uart); #endif } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 7c693bf6c..9a8035c26 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -39,8 +39,7 @@ typedef struct { uint8_t* buffer; uint32_t bufsize; - volatile uint32_t rx_count; - volatile bool receiving; + volatile int32_t rx_count; } busio_uart_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H -- cgit v1.2.3 From 4015023e01f233fa62f6bcd329a2cd50f8b99411 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Sep 2018 16:06:44 +0700 Subject: clean up uart io --- ports/nrf/common-hal/busio/UART.c | 68 ++++++++++++++++++++++++--------------- ports/nrf/common-hal/busio/UART.h | 4 +++ 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 6f4e0af8e..7e6fddf2f 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -38,8 +38,6 @@ #include "nrfx_uarte.h" #include -static nrfx_uarte_t _uart = NRFX_UARTE_INSTANCE(0); - // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ do {\ @@ -75,8 +73,8 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - if ( (tx == mp_const_none) || (rx == mp_const_none) ) { - mp_raise_ValueError(translate("Invalid pins")); + if ( (tx == mp_const_none) && (rx == mp_const_none) ) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); } if ( receiver_buffer_size == 0 ) { @@ -88,8 +86,8 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, } nrfx_uarte_config_t config = { - .pseltxd = tx->number, - .pselrxd = rx->number, + .pseltxd = (tx == mp_const_none) ? NRF_UART_PSEL_DISCONNECTED : tx->number, + .pselrxd = (rx == mp_const_none) ? NRF_UART_PSEL_DISCONNECTED : rx->number, .pselcts = NRF_UART_PSEL_DISCONNECTED, .pselrts = NRF_UART_PSEL_DISCONNECTED, .p_context = self, @@ -99,16 +97,26 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, .interrupt_priority = 7 }; - nrfx_uarte_uninit(&_uart); - _VERIFY_ERR(nrfx_uarte_init(&_uart, &config, uart_callback_irq)); + // support only 1 instance for now + self->uarte = (nrfx_uarte_t ) NRFX_UARTE_INSTANCE(0); + nrfx_uarte_uninit(&self->uarte); + _VERIFY_ERR(nrfx_uarte_init(&self->uarte, &config, uart_callback_irq)); // Init buffer for rx - self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); - if ( !self->buffer ) { - nrfx_uarte_uninit(&_uart); - mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + if ( rx != mp_const_none ) { + self->buffer = (uint8_t *) gc_alloc(receiver_buffer_size, false, false); + if ( !self->buffer ) { + nrfx_uarte_uninit(&self->uarte); + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + } + self->bufsize = receiver_buffer_size; + + claim_pin(rx); + } + + if ( tx != mp_const_none ) { + claim_pin(tx); } - self->bufsize = receiver_buffer_size; self->baudrate = baudrate; self->timeout_ms = timeout; @@ -119,8 +127,8 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - return (nrf_uarte_rx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED) || - (nrf_uarte_tx_pin_get(_uart.p_reg) == NRF_UART_PSEL_DISCONNECTED); + return (nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED) && + (nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED); #endif } @@ -129,7 +137,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else if ( !common_hal_busio_uart_deinited(self) ) { - nrfx_uarte_uninit(&_uart); + nrfx_uarte_uninit(&self->uarte); gc_free(self->buffer); } #endif @@ -142,6 +150,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t return 0; #else + if ( nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { + mp_raise_ValueError(translate("No RX pin")); + } + size_t remain = len; uint64_t start_ticks = ticks_ms; @@ -149,7 +161,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t const size_t cnt = MIN(self->bufsize, len); self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&_uart, self->buffer, cnt)); + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt)); while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP @@ -159,7 +171,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Time up, abort rx use received so far if ( self->rx_count == -1 ) { - nrfx_uarte_rx_abort(&_uart); + nrfx_uarte_rx_abort(&self->uarte); while ( self->rx_count == -1 ) { } } @@ -181,18 +193,22 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return 0; #else + if ( nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { + mp_raise_ValueError(translate("No TX pin")); + } + if ( len == 0 ) return 0; - if ( !nrfx_uarte_tx_in_progress(&_uart) ) { - nrfx_uarte_tx_abort(&_uart); + if ( !nrfx_uarte_tx_in_progress(&self->uarte) ) { + nrfx_uarte_tx_abort(&self->uarte); } - (*errcode) = nrfx_uarte_tx(&_uart, data, len); + (*errcode) = nrfx_uarte_tx(&self->uarte, data, len); _VERIFY_ERR(*errcode); (*errcode) = 0; uint64_t start_ticks = ticks_ms; - while ( nrfx_uarte_tx_in_progress(&_uart) && (ticks_ms - start_ticks < self->timeout_ms) ) { + while ( nrfx_uarte_tx_in_progress(&self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif @@ -214,7 +230,7 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else self->baudrate = baudrate; - nrf_uarte_baudrate_set(_uart.p_reg, get_nrf_baud(baudrate)); + nrf_uarte_baudrate_set(self->uarte.p_reg, get_nrf_baud(baudrate)); #endif } @@ -222,12 +238,12 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - return 1; // nrf_uart_event_check(_uart.p_reg, NRF_UART_EVENT_RXDRDY) ? 1 : 0; + return 1; // nrf_uart_event_check(self->uarte.p_reg, NRF_UART_EVENT_RXDRDY) ? 1 : 0; #endif } void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { @@ -235,7 +251,7 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); return false; #else - return !nrfx_uarte_tx_in_progress(&_uart); + return !nrfx_uarte_tx_in_progress(&self->uarte); #endif } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 9a8035c26..aef377f14 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -28,12 +28,16 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H #include "common-hal/microcontroller/Pin.h" +#include "nrfx_uarte.h" #include "py/obj.h" #include "py/ringbuf.h" typedef struct { mp_obj_base_t base; + + nrfx_uarte_t uarte; + uint32_t baudrate; uint32_t timeout_ms; -- cgit v1.2.3 From 1782ceab356d3c02f7d4a4319a6552654933da15 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Sep 2018 16:18:49 +0700 Subject: uarte malloc if buffer is not in SRAM --- ports/nrf/common-hal/busio/UART.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 7e6fddf2f..5bb51bb74 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -203,7 +203,14 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, nrfx_uarte_tx_abort(&self->uarte); } - (*errcode) = nrfx_uarte_tx(&self->uarte, data, len); + // EasyDMA can only access SRAM + uint8_t * tx_buf = (uint8_t*) data; + if ( !nrfx_is_in_ram(data) ) { + tx_buf = (uint8_t *) gc_alloc(len, false, false); + memcpy(tx_buf, data, len); + } + + (*errcode) = nrfx_uarte_tx(&self->uarte, tx_buf, len); _VERIFY_ERR(*errcode); (*errcode) = 0; @@ -214,6 +221,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, #endif } + if ( !nrfx_is_in_ram(data) ) { + gc_free(tx_buf); + } + return len; #endif } -- cgit v1.2.3 From 01c129619734103cf742a5b66865a9900cbc43ae Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 12:37:31 +0700 Subject: nrf52 uart io rx work reliably --- ports/nrf/common-hal/busio/UART.c | 66 +++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 5bb51bb74..48951fe1b 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -37,6 +37,7 @@ #include "tick.h" #include "nrfx_uarte.h" #include +#include // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ @@ -47,17 +48,38 @@ }\ }while(0) +#define UARTE_DEBUG 0 + +#if UARTE_DEBUG +#define PRINT_INT(x) printf("%s: %d: " #x " = %ld\n" , __FUNCTION__, __LINE__, (uint32_t) (x) ) +#else +#define PRINT_INT(x) +#endif + static uint32_t get_nrf_baud (uint32_t baudrate); +static uint32_t _err = 0; +static uint32_t _err_count = 0; + + static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { + case NRFX_UART_EVT_RX_DONE: + self->rx_count = event->data.rxtx.bytes; + break; + case NRFX_UART_EVT_TX_DONE: break; - case NRFX_UART_EVT_RX_DONE: - self->rx_count = event->data.rxtx.bytes; + case NRFX_UART_EVT_ERROR: + // Abort too fast will cause error occasionally + if ( self->rx_count == -1 ) { + self->rx_count = 0; // event->data.error.rxtx.bytes; + } + _err_count = event->data.error.rxtx.bytes; + _err = event->data.error.error_mask; break; default: @@ -120,6 +142,10 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, self->baudrate = baudrate; self->timeout_ms = timeout; + + // queue 1-byte transfer for rx_characters_available() + self->rx_count = -1; + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); #endif } @@ -157,32 +183,40 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t size_t remain = len; uint64_t start_ticks = ticks_ms; - while ( remain && (ticks_ms - start_ticks < self->timeout_ms) ) { - const size_t cnt = MIN(self->bufsize, len); - - self->rx_count = -1; - _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt)); - + while ( 1 ) { + // Wait for on-going reception to complete while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif } - // Time up, abort rx use received so far - if ( self->rx_count == -1 ) { - nrfx_uarte_rx_abort(&self->uarte); - while ( self->rx_count == -1 ) { - } - } - + // copy received data if ( self->rx_count > 0 ) { memcpy(data, self->buffer, self->rx_count); data += self->rx_count; remain -= self->rx_count; + + self->rx_count = 0; } + + // exit if complete or time up + if ( !remain || !(ticks_ms - start_ticks < self->timeout_ms) ) { + break; + } + + // prepare next receiving + const size_t cnt = MIN(self->bufsize, remain); + self->rx_count = -1; + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt)); } + // queue 1-byte transfer for rx_characters_available() + if ( self->rx_count == 0 ) { + self->rx_count = -1; + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); + } + return len - remain; #endif } @@ -249,7 +283,7 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - return 1; // nrf_uart_event_check(self->uarte.p_reg, NRF_UART_EVENT_RXDRDY) ? 1 : 0; + return (self->rx_count > 0) ? 1 : 0; #endif } -- cgit v1.2.3 From d7144799249c12e66c1b00e6c0857fc8cfe11345 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 12:48:48 +0700 Subject: clean up --- ports/nrf/common-hal/busio/UART.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 48951fe1b..737e5007e 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -48,20 +48,8 @@ }\ }while(0) -#define UARTE_DEBUG 0 - -#if UARTE_DEBUG -#define PRINT_INT(x) printf("%s: %d: " #x " = %ld\n" , __FUNCTION__, __LINE__, (uint32_t) (x) ) -#else -#define PRINT_INT(x) -#endif - static uint32_t get_nrf_baud (uint32_t baudrate); -static uint32_t _err = 0; -static uint32_t _err_count = 0; - - static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { busio_uart_obj_t* self = (busio_uart_obj_t*) context; @@ -74,12 +62,9 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) break; case NRFX_UART_EVT_ERROR: - // Abort too fast will cause error occasionally if ( self->rx_count == -1 ) { - self->rx_count = 0; // event->data.error.rxtx.bytes; + self->rx_count = 0; } - _err_count = event->data.error.rxtx.bytes; - _err = event->data.error.error_mask; break; default: @@ -184,7 +169,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t uint64_t start_ticks = ticks_ms; while ( 1 ) { - // Wait for on-going reception to complete + // Wait for on-going transfer to complete while ( (self->rx_count == -1) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP @@ -233,8 +218,19 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, if ( len == 0 ) return 0; - if ( !nrfx_uarte_tx_in_progress(&self->uarte) ) { - nrfx_uarte_tx_abort(&self->uarte); + uint64_t start_ticks = ticks_ms; + + // Wait for on-going transfer to complete + while ( nrfx_uarte_tx_in_progress(&self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + // Time up + if ( !(ticks_ms - start_ticks < self->timeout_ms) ) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; } // EasyDMA can only access SRAM @@ -248,7 +244,6 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, _VERIFY_ERR(*errcode); (*errcode) = 0; - uint64_t start_ticks = ticks_ms; while ( nrfx_uarte_tx_in_progress(&self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP @@ -283,7 +278,7 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { #ifndef NRF52840_XXAA mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); #else - return (self->rx_count > 0) ? 1 : 0; + return (self->rx_count > 0) ? self->rx_count : 0; #endif } -- cgit v1.2.3 From d3e5ba83eb031770e063fd5934b990767f1da692 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 13:00:57 +0700 Subject: update nrfx to 1.3.0 --- lib/tinyusb | 2 +- ports/nrf/common-hal/busio/UART.c | 1 - ports/nrf/nrfx | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 583326e53..a660fb0cf 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 583326e535454f16b06ebdb9cc06869602a5564c +Subproject commit a660fb0cfc8641d5645d1cdea76027266b278388 diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 737e5007e..0b5bb915c 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -37,7 +37,6 @@ #include "tick.h" #include "nrfx_uarte.h" #include -#include // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ diff --git a/ports/nrf/nrfx b/ports/nrf/nrfx index 293f553ed..67710e47c 160000 --- a/ports/nrf/nrfx +++ b/ports/nrf/nrfx @@ -1 +1 @@ -Subproject commit 293f553ed9551c1fdfd05eac48e75bbdeb4e7290 +Subproject commit 67710e47c7313cc56a15748e485079831ee6a3af -- cgit v1.2.3 From 9017c9d29af17767e1a846339556e89de0f7c1b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 14:29:45 +0700 Subject: clean up --- ports/nrf/common-hal/busio/UART.c | 96 +++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 0b5bb915c..3269e2183 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -38,6 +38,8 @@ #include "nrfx_uarte.h" #include +#ifdef NRF52840_XXAA + // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ do {\ @@ -53,14 +55,14 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) busio_uart_obj_t* self = (busio_uart_obj_t*) context; switch ( event->type ) { - case NRFX_UART_EVT_RX_DONE: + case NRFX_UARTE_EVT_RX_DONE: self->rx_count = event->data.rxtx.bytes; break; - case NRFX_UART_EVT_TX_DONE: + case NRFX_UARTE_EVT_TX_DONE: break; - case NRFX_UART_EVT_ERROR: + case NRFX_UARTE_EVT_ERROR: if ( self->rx_count == -1 ) { self->rx_count = 0; } @@ -76,9 +78,6 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, uint8_t receiver_buffer_size) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#else if ( (tx == mp_const_none) && (rx == mp_const_none) ) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } @@ -130,36 +129,22 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, // queue 1-byte transfer for rx_characters_available() self->rx_count = -1; _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); -#endif } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#else return (nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED) && (nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED); -#endif } void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#else if ( !common_hal_busio_uart_deinited(self) ) { nrfx_uarte_uninit(&self->uarte); gc_free(self->buffer); } -#endif } // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); - return 0; -#else - if ( nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { mp_raise_ValueError(translate("No RX pin")); } @@ -202,15 +187,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t } return len - remain; -#endif } // Write characters. size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); - return 0; -#else if ( nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { mp_raise_ValueError(translate("No TX pin")); } @@ -254,13 +234,9 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, } return len; -#endif } uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#endif return self->baudrate; } @@ -274,11 +250,7 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#else return (self->rx_count > 0) ? self->rx_count : 0; -#endif } void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { @@ -286,12 +258,7 @@ void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); - return false; -#else return !nrfx_uarte_tx_in_progress(&self->uarte); -#endif } static uint32_t get_nrf_baud (uint32_t baudrate) @@ -345,3 +312,56 @@ static uint32_t get_nrf_baud (uint32_t baudrate) return NRF_UART_BAUDRATE_1000000; } } + +#else + +void common_hal_busio_uart_construct (busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, + uint8_t receiver_buffer_size) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +} + +bool common_hal_busio_uart_deinited (busio_uart_obj_t *self) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + return true; +} + +void common_hal_busio_uart_deinit (busio_uart_obj_t *self) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +} + +// Read characters. +size_t common_hal_busio_uart_read (busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + return 0; +} + +// Write characters. +size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + return 0; +} + +uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t *self) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + return self->baudrate; +} + +void common_hal_busio_uart_set_baudrate (busio_uart_obj_t *self, uint32_t baudrate) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +} + +uint32_t common_hal_busio_uart_rx_characters_available (busio_uart_obj_t *self) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); +} + +void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t *self) { + +} + +bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t *self) { + mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + return false; +} +#endif -- cgit v1.2.3 From 2f0e0bdcaf18db1766c54b8ab875447f97783079 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 16:14:44 +0700 Subject: migrate serial from uart to uarte --- ports/nrf/boards/feather_nrf52832/mpconfigboard.h | 1 - ports/nrf/common-hal/busio/UART.c | 20 +++++------ ports/nrf/mphalport.c | 34 ++++++++++-------- ports/nrf/mphalport.h | 13 +++---- ports/nrf/nrfx_config.h | 10 ------ ports/nrf/supervisor/serial.c | 43 +++++++++++++---------- 6 files changed, 57 insertions(+), 64 deletions(-) diff --git a/ports/nrf/boards/feather_nrf52832/mpconfigboard.h b/ports/nrf/boards/feather_nrf52832/mpconfigboard.h index 0da1abfc4..e751ec182 100644 --- a/ports/nrf/boards/feather_nrf52832/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52832/mpconfigboard.h @@ -30,7 +30,6 @@ #define MICROPY_HW_UART_RX NRF_GPIO_PIN_MAP(0, 8) #define MICROPY_HW_UART_TX NRF_GPIO_PIN_MAP(0, 6) -#define MICROPY_HW_UART_HWFC (0) #define PORT_HEAP_SIZE (32 * 1024) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 3269e2183..ab71cad78 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -91,13 +91,13 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, } nrfx_uarte_config_t config = { - .pseltxd = (tx == mp_const_none) ? NRF_UART_PSEL_DISCONNECTED : tx->number, - .pselrxd = (rx == mp_const_none) ? NRF_UART_PSEL_DISCONNECTED : rx->number, - .pselcts = NRF_UART_PSEL_DISCONNECTED, - .pselrts = NRF_UART_PSEL_DISCONNECTED, + .pseltxd = (tx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, + .pselrxd = (rx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, .p_context = self, - .hwfc = NRF_UART_HWFC_DISABLED, - .parity = (parity == PARITY_NONE) ? NRF_UART_PARITY_EXCLUDED : NRF_UART_PARITY_INCLUDED, + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = (parity == PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED, .baudrate = get_nrf_baud(baudrate), .interrupt_priority = 7 }; @@ -132,8 +132,8 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { - return (nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED) && - (nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED); + return (nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UARTE_PSEL_DISCONNECTED) && + (nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UARTE_PSEL_DISCONNECTED); } void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { @@ -145,7 +145,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { - if ( nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { + if ( nrf_uarte_rx_pin_get(self->uarte.p_reg) == NRF_UARTE_PSEL_DISCONNECTED ) { mp_raise_ValueError(translate("No RX pin")); } @@ -191,7 +191,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Write characters. size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { - if ( nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UART_PSEL_DISCONNECTED ) { + if ( nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UARTE_PSEL_DISCONNECTED ) { mp_raise_ValueError(translate("No TX pin")); } diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 163ac8d60..27ed57bf3 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -27,36 +27,40 @@ #include -#include "mphalport.h" +#include "py/mphal.h" #include "py/mpstate.h" - +#include "py/gc.h" #if (MICROPY_PY_BLE_NUS == 0) #if !defined( NRF52840_XXAA) int mp_hal_stdin_rx_chr(void) { - uint8_t data = 0; - - while (!nrfx_uart_rx_ready(&serial_instance)); - - const nrfx_err_t err = nrfx_uart_rx(&serial_instance, &data, sizeof(data)); - if (err == NRFX_SUCCESS) - NRFX_ASSERT(err); - + uint8_t data; + nrfx_uarte_rx(&serial_instance, &data, 1); return data; } bool mp_hal_stdin_any(void) { - return nrfx_uart_rx_ready(&serial_instance); + return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY); } void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { - if (len == 0) + if (len == 0) { return; + } - const nrfx_err_t err = nrfx_uart_tx(&serial_instance, (uint8_t*)str, len); - if (err == NRFX_SUCCESS) - NRFX_ASSERT(err); + // EasyDMA can only access SRAM + uint8_t * tx_buf = (uint8_t*) str; + if ( !nrfx_is_in_ram(str) ) { + tx_buf = (uint8_t *) gc_alloc(len, false, false); + memcpy(tx_buf, str, len); + } + + nrfx_uarte_tx(&serial_instance, tx_buf, len); + + if ( !nrfx_is_in_ram(str) ) { + gc_free(tx_buf); + } } #else diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h index f283cf38d..a1929a4ac 100644 --- a/ports/nrf/mphalport.h +++ b/ports/nrf/mphalport.h @@ -31,21 +31,16 @@ #include #include "lib/utils/interrupt_char.h" -#include "nrfx_uart.h" +#include "nrfx_uarte.h" #include "py/mpconfig.h" -extern nrfx_uart_t serial_instance; +extern nrfx_uarte_t serial_instance; extern volatile uint64_t ticks_ms; -static inline mp_uint_t mp_hal_ticks_ms(void) { - return ticks_ms; -} +#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms) +#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) -int mp_hal_stdin_rx_chr(void); -void mp_hal_stdout_tx_str(const char *str); bool mp_hal_stdin_any(void); -void mp_hal_delay_ms(mp_uint_t ms); -#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) #endif diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index 0ccfecb21..f217cb053 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -45,18 +45,8 @@ #define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 // UART -#if 0 -#define NRFX_UART_ENABLED 1 -#define NRFX_UART0_ENABLED 1 -#else #define NRFX_UARTE_ENABLED 1 #define NRFX_UARTE0_ENABLED 1 -#endif - -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 7 -#define NRFX_UART_DEFAULT_CONFIG_HWFC NRF_UART_HWFC_DISABLED -#define NRFX_UART_DEFAULT_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED -#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE NRF_UART_BAUDRATE_115200 // PWM #define NRFX_PWM0_ENABLED 1 diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index 18a45f10b..cfbcc4b31 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -24,19 +24,19 @@ * THE SOFTWARE. */ -#include "mphalport.h" +#include "py/mphal.h" #if MICROPY_PY_BLE_NUS #include "ble_uart.h" #else #include "nrf_gpio.h" +#include "nrfx_uarte.h" #endif -#if !defined( NRF52840_XXAA) +#if !defined(NRF52840_XXAA) -#define INST_NO 0 - -nrfx_uart_t serial_instance = NRFX_UART_INSTANCE(INST_NO); +uint8_t serial_received_char; +nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0); void serial_init(void) { #if MICROPY_PY_BLE_NUS @@ -45,22 +45,27 @@ void serial_init(void) { ; } #else - nrfx_uart_config_t config = NRFX_UART_DEFAULT_CONFIG; - config.pseltxd = MICROPY_HW_UART_TX; - config.pselrxd = MICROPY_HW_UART_RX; - config.hwfc = MICROPY_HW_UART_HWFC ? NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED; -#ifdef MICROPY_HW_UART_CTS - config.pselcts = MICROPY_HW_UART_CTS; -#endif -#ifdef MICROPY_HW_UART_RTS - config.pselrts = MICROPY_HW_UART_RTS; -#endif - - const nrfx_err_t err = nrfx_uart_init(&serial_instance, &config, NULL); - if (err == NRFX_SUCCESS) + nrfx_uarte_config_t config = { + .pseltxd = MICROPY_HW_UART_TX, + .pselrxd = MICROPY_HW_UART_RX, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + .baudrate = NRF_UARTE_BAUDRATE_115200, + .interrupt_priority = 7 + }; + + nrfx_uarte_uninit(&serial_instance); + const nrfx_err_t err = nrfx_uarte_init(&serial_instance, &config, NULL); // no callback for blocking mode + + if (err != NRFX_SUCCESS) { NRFX_ASSERT(err); + } - nrfx_uart_rx_enable(&serial_instance); + // enabled receiving + nrf_uarte_task_trigger(serial_instance.p_reg, NRF_UARTE_TASK_STARTRX); #endif } -- cgit v1.2.3 From dec5c50c45ab0e8212a80e27cabb389f2792d55a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 16:22:14 +0700 Subject: clean up --- ports/nrf/common-hal/busio/UART.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index ab71cad78..28fcdc150 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -264,52 +264,52 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { static uint32_t get_nrf_baud (uint32_t baudrate) { if ( baudrate <= 1200 ) { - return NRF_UART_BAUDRATE_1200; + return NRF_UARTE_BAUDRATE_1200; } else if ( baudrate <= 2400 ) { - return NRF_UART_BAUDRATE_2400; + return NRF_UARTE_BAUDRATE_2400; } else if ( baudrate <= 4800 ) { - return NRF_UART_BAUDRATE_4800; + return NRF_UARTE_BAUDRATE_4800; } else if ( baudrate <= 9600 ) { - return NRF_UART_BAUDRATE_9600; + return NRF_UARTE_BAUDRATE_9600; } else if ( baudrate <= 14400 ) { - return NRF_UART_BAUDRATE_14400; + return NRF_UARTE_BAUDRATE_14400; } else if ( baudrate <= 19200 ) { - return NRF_UART_BAUDRATE_19200; + return NRF_UARTE_BAUDRATE_19200; } else if ( baudrate <= 28800 ) { - return NRF_UART_BAUDRATE_28800; + return NRF_UARTE_BAUDRATE_28800; } else if ( baudrate <= 38400 ) { - return NRF_UART_BAUDRATE_38400; + return NRF_UARTE_BAUDRATE_38400; } else if ( baudrate <= 57600 ) { - return NRF_UART_BAUDRATE_57600; + return NRF_UARTE_BAUDRATE_57600; } else if ( baudrate <= 76800 ) { - return NRF_UART_BAUDRATE_76800; + return NRF_UARTE_BAUDRATE_76800; } else if ( baudrate <= 115200 ) { - return NRF_UART_BAUDRATE_115200; + return NRF_UARTE_BAUDRATE_115200; } else if ( baudrate <= 230400 ) { - return NRF_UART_BAUDRATE_230400; + return NRF_UARTE_BAUDRATE_230400; } else if ( baudrate <= 250000 ) { - return NRF_UART_BAUDRATE_250000; + return NRF_UARTE_BAUDRATE_250000; } else if ( baudrate <= 460800 ) { - return NRF_UART_BAUDRATE_460800; + return NRF_UARTE_BAUDRATE_460800; } else if ( baudrate <= 921600 ) { - return NRF_UART_BAUDRATE_921600; + return NRF_UARTE_BAUDRATE_921600; } else { - return NRF_UART_BAUDRATE_1000000; + return NRF_UARTE_BAUDRATE_1000000; } } -- cgit v1.2.3 From f724647a45eb8fa8cd2691a2a9a73e8e5dec409d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 17:09:54 +0700 Subject: fix feather nrf52840 build error --- ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index 81818741d..bd6d4b244 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -67,5 +67,5 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_P0_23) #define DEFAULT_SPI_BUS_MISO (&pin_P0_22) -#define DEFAULT_UART_BUS_RX (&pin_P1_0) +#define DEFAULT_UART_BUS_RX (&pin_P1_00) #define DEFAULT_UART_BUS_TX (&pin_P0_24) -- cgit v1.2.3 From 74cc55b107bd41808ad2cce35493ffc51eb1c051 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Sep 2018 17:31:53 +0700 Subject: change error type to runtime --- ports/nrf/common-hal/busio/UART.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 28fcdc150..c209be89d 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -45,7 +45,7 @@ do {\ uint32_t _err = (_exp);\ if (NRFX_SUCCESS != _err ) {\ - mp_raise_msg_varg(&mp_type_AssertionError, translate("error = 0x%08lX "), _err);\ + mp_raise_msg_varg(&mp_type_RuntimeError, translate("error = 0x%08lX "), _err);\ }\ }while(0) -- cgit v1.2.3 From 52328c88cd5271c9b82dd03ef9ca19b0abc34e6f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Sep 2018 02:06:32 +0700 Subject: remove space --- ports/nrf/common-hal/busio/UART.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index c209be89d..86fe64726 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -45,7 +45,7 @@ do {\ uint32_t _err = (_exp);\ if (NRFX_SUCCESS != _err ) {\ - mp_raise_msg_varg(&mp_type_RuntimeError, translate("error = 0x%08lX "), _err);\ + mp_raise_msg_varg(&mp_type_RuntimeError, translate("error = 0x%08lX"), _err);\ }\ }while(0) -- cgit v1.2.3 From eba80f7a9939f6ac48fcadeb1c46082b0e8d7575 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Sep 2018 02:10:44 +0700 Subject: update translate string --- locale/circuitpython.pot | 29 +++++++++++++++++++++++------ locale/de_DE.po | 31 +++++++++++++++++++++++++------ locale/en_US.po | 29 +++++++++++++++++++++++------ locale/es.po | 31 +++++++++++++++++++++++++------ locale/fil.po | 31 +++++++++++++++++++++++++------ locale/fr.po | 31 +++++++++++++++++++++++++------ ports/nrf/common-hal/busio/UART.c | 2 +- 7 files changed, 147 insertions(+), 37 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 513ec8efd..05cb73287 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -378,10 +378,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "" @@ -390,10 +392,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "" @@ -702,11 +706,24 @@ msgstr "" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 72f7b254d..098e065d0 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -387,10 +387,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "Konnte keinen RX Buffer allozieren" @@ -399,10 +401,12 @@ msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "Kein RX Pin" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "Kein TX Pin" @@ -713,11 +717,26 @@ msgstr "Alle timer werden benutzt" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "ungültiger dupterm index" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "bytes mit merh als 8 bits werden nicht unterstützt" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index 63ae50ba5..c57949b67 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -378,10 +378,12 @@ msgid "bytes > 8 bits not supported" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "" @@ -390,10 +392,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "" @@ -702,11 +706,24 @@ msgstr "" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "" diff --git a/locale/es.po b/locale/es.po index 48cfdcda8..9d8f057be 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -393,10 +393,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no son soportados" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "tx y rx no pueden ser ambos None" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "Fallo la asignación del buffer RX" @@ -405,10 +407,12 @@ msgid "Could not initialize UART" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "" @@ -718,11 +722,26 @@ msgstr "Todos los timers están siendo utilizados" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "index dupterm inválido" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "bytes > 8 bits no son soportados" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index ad6252a21..6223463da 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -390,10 +390,12 @@ msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "Nabigong ilaan ang RX buffer" @@ -402,10 +404,12 @@ msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "Walang RX pin" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "Walang TX pin" @@ -719,11 +723,26 @@ msgstr "Lahat ng timer ginagamit" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "mali ang buffer length" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "hindi sinusuportahan ang bytes > 8 bits" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "hindi pa implemented ang busio.UART" diff --git a/locale/fr.po b/locale/fr.po index d6d7b6087..3b3baca84 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-09-26 02:09+0700\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -385,10 +385,12 @@ msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "TX et RX ne peuvent être None tous les deux" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "Echec de l'allocation du tampon RX" @@ -397,10 +399,12 @@ msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "Pas de broche RX" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "Pas de broche TX" @@ -715,11 +719,26 @@ msgstr "Tous les timers sont utilisés" msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "longueur de tampon invalide" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "octets > 8 bits non supporté" + +#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 +#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 +#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not yet implemented" msgstr "busio.UART pas encore implémenté" diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 86fe64726..40be66b65 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -87,7 +87,7 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, } if ( parity == PARITY_ODD ) { - mp_raise_ValueError(translate("busio.UART odd parity is not supported")); + mp_raise_ValueError(translate("Odd parity is not supported")); } nrfx_uarte_config_t config = { -- cgit v1.2.3 From 76d6fb03f0ffabe3886ed5a493faa02041f91179 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Sep 2018 02:12:06 +0700 Subject: more clean up --- ports/nrf/common-hal/busio/UART.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 40be66b65..d3bd2a854 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -241,12 +241,8 @@ uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { } void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { -#ifndef NRF52840_XXAA - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); -#else self->baudrate = baudrate; nrf_uarte_baudrate_set(self->uarte.p_reg, get_nrf_baud(baudrate)); -#endif } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { -- cgit v1.2.3 From f3f549b4550f3cfbe2faea9c1d0d305cf5dfb959 Mon Sep 17 00:00:00 2001 From: Carlos Date: Sat, 29 Sep 2018 21:32:57 -0500 Subject: Start with translation of ESP strings. --- locale/es.po | 82 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/locale/es.po b/locale/es.po index 48cfdcda8..0d667e3f5 100644 --- a/locale/es.po +++ b/locale/es.po @@ -343,11 +343,11 @@ msgstr "pin inválido" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 msgid "Invalid pin for left channel" -msgstr "" +msgstr "Pin inválido para canal izquierdo" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 msgid "Invalid pin for right channel" -msgstr "" +msgstr "Pin inválido para canal derecho" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 msgid "Cannot output both channels on the same pin" @@ -366,7 +366,7 @@ msgstr "Todos los canales de eventos están siendo utilizados" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "" +msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor que %d" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" @@ -382,11 +382,11 @@ msgstr "pines inválidos" #: ports/atmel-samd/common-hal/busio/I2C.c:101 msgid "SDA or SCL needs a pull up" -msgstr "" +msgstr "SDA o SCL necesitan una pull up" #: ports/atmel-samd/common-hal/busio/I2C.c:121 msgid "Unsupported baudrate" -msgstr "" +msgstr "Baudrate sin soporte" #: ports/atmel-samd/common-hal/busio/UART.c:66 msgid "bytes > 8 bits not supported" @@ -402,31 +402,31 @@ msgstr "Fallo la asignación del buffer RX" #: ports/atmel-samd/common-hal/busio/UART.c:153 msgid "Could not initialize UART" -msgstr "" +msgstr "No se pudo inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:240 msgid "No RX pin" -msgstr "" +msgstr "Sin pin RX" #: ports/atmel-samd/common-hal/busio/UART.c:294 msgid "No TX pin" -msgstr "" +msgstr "Sin pin TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 #: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 msgid "Cannot get pull while in output mode" -msgstr "" +msgstr "No se puede obtener pull mientras en modo de salida" #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." -msgstr "" +msgstr "No se puede reiniciar en bootloader porque no hay bootloader presente." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 #: ports/nrf/common-hal/pulseio/PWMOut.c:227 msgid "Invalid PWM frequency" -msgstr "" +msgstr "Frecuencia PWM inválida" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 msgid "All timers for this pin are in use" @@ -434,7 +434,7 @@ msgstr "Todos los timers para este pin están siendo utilizados" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 msgid "No hardware support on pin" -msgstr "" +msgstr "pin no tiene soporte en hardware" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 msgid "EXTINT channel already in use" @@ -449,16 +449,16 @@ msgstr "Fallo la asignación del buffer RX de %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 msgid "pop from an empty PulseIn" -msgstr "" +msgstr "pop en un PulseIn vacío" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 #: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 msgid "index out of range" -msgstr "" +msgstr "index fuera de rango" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 msgid "Another send is already active" -msgstr "" +msgstr "Otro envío ya está activo" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 msgid "Both pins must support hardware interrupts" @@ -474,11 +474,11 @@ msgstr "Valor de calibración fuera de rango +/-127" #: ports/atmel-samd/common-hal/storage/__init__.c:48 msgid "Cannot remount '/' when USB is active." -msgstr "" +msgstr "No se puede volver a montar '/' cuando el USB esta activo." #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" -msgstr "" +msgstr "Sin GCLKs libres" #: ports/atmel-samd/common-hal/usb_hid/Device.c:78 #: ports/nrf/common-hal/usb_hid/Device.c:45 @@ -489,48 +489,48 @@ msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes." #: ports/atmel-samd/common-hal/usb_hid/Device.c:82 #: ports/nrf/common-hal/usb_hid/Device.c:53 msgid "USB Busy" -msgstr "" +msgstr "USB ocupado" #: ports/atmel-samd/common-hal/usb_hid/Device.c:82 #: ports/nrf/common-hal/usb_hid/Device.c:59 msgid "USB Error" -msgstr "" +msgstr "Error USB" #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" -msgstr "" +msgstr "Pin %q no tiene capacidades ADC" #: ports/esp8266/common-hal/analogio/AnalogOut.c:39 msgid "No hardware support for analog out." -msgstr "" +msgstr "Sin soporte de hardware para salida análoga" #: ports/esp8266/common-hal/busio/SPI.c:72 msgid "Pins not valid for SPI" -msgstr "" +msgstr "Pines no válidos para SPI" #: ports/esp8266/common-hal/busio/UART.c:45 msgid "Only tx supported on UART1 (GPIO2)." -msgstr "" +msgstr "Solo tx soportada en UART1 (GPIO2)" #: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 msgid "invalid data bits" -msgstr "" +msgstr "data bits inválidos" #: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 msgid "invalid stop bits" -msgstr "" +msgstr "stop bits inválidos" #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 msgid "ESP8266 does not support pull down." -msgstr "" +msgstr "ESP8266 no tiene soporte para pull down" #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 msgid "GPIO16 does not support pull up." -msgstr "GPIO16 no soporta pull up." +msgstr "GPIO16 no tiene soporte para pull up." #: ports/esp8266/common-hal/microcontroller/__init__.c:66 msgid "ESP8226 does not support safe mode." -msgstr "ESP8226 no soporta modo seguro" +msgstr "ESP8226 no tiene soporte para modo seguro" #: ports/esp8266/common-hal/pulseio/PWMOut.c:54 #: ports/esp8266/common-hal/pulseio/PWMOut.c:113 @@ -564,58 +564,58 @@ msgstr "No se pudo montar de nuevo el sistema de archivos" #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "" +msgstr "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" -msgstr "" +msgstr "C-level assert" #: ports/esp8266/machine_adc.c:57 #, c-format msgid "not a valid ADC Channel: %d" -msgstr "" +msgstr "no es un canal ADC válido: %d" #: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 msgid "impossible baudrate" -msgstr "" +msgstr "baudrate imposible" #: ports/esp8266/machine_pin.c:129 msgid "expecting a pin" -msgstr "" +msgstr "esperando un pin" #: ports/esp8266/machine_pin.c:284 msgid "Pin(16) doesn't support pull" -msgstr "" +msgstr "Pin(16) no tiene soporte para pull" #: ports/esp8266/machine_pin.c:323 msgid "invalid pin" -msgstr "" +msgstr "pin inválido" #: ports/esp8266/machine_pin.c:389 msgid "pin does not have IRQ capabilities" -msgstr "" +msgstr "pin no tiene capacidades IRQ" #: ports/esp8266/machine_rtc.c:185 msgid "buffer too long" -msgstr "" +msgstr "buffer demasiado largo" #: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 #: ports/esp8266/machine_rtc.c:246 msgid "invalid alarm" -msgstr "" +msgstr "alarma inválida" #: ports/esp8266/machine_uart.c:169 #, c-format msgid "UART(%d) does not exist" -msgstr "" +msgstr "UART(%d) no existe" #: ports/esp8266/machine_uart.c:219 msgid "UART(1) can't read" -msgstr "" +msgstr "UART(1) no puede leer" #: ports/esp8266/modesp.c:119 msgid "len must be multiple of 4" -msgstr "" +msgstr "len debe de ser múltiple de 4" #: ports/esp8266/modesp.c:274 #, c-format -- cgit v1.2.3 From 1ae4616ee2845771d740e1f392b2894c403cf072 Mon Sep 17 00:00:00 2001 From: Carlos Date: Sun, 30 Sep 2018 12:04:22 -0500 Subject: Finish translation of strings on the ESP port --- locale/es.po | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/locale/es.po b/locale/es.po index 0d667e3f5..5120c74f2 100644 --- a/locale/es.po +++ b/locale/es.po @@ -620,87 +620,87 @@ msgstr "len debe de ser múltiple de 4" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "" +msgstr "la asignación de memoria ha fallado, asignando %u bytes para código nativo" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" -msgstr "" +msgstr "la ubicación de la flash debe estar debajo de 1MByte" #: ports/esp8266/modmachine.c:63 msgid "frequency can only be either 80Mhz or 160MHz" -msgstr "" +msgstr "la frecuencia solo puede ser 80MHz o 160MHz" #: ports/esp8266/modnetwork.c:61 msgid "AP required" -msgstr "" +msgstr "AP necesario" #: ports/esp8266/modnetwork.c:61 msgid "STA required" -msgstr "" +msgstr "STA necesario" #: ports/esp8266/modnetwork.c:87 msgid "Cannot update i/f status" -msgstr "" +msgstr "No se puede actualizar i/f status" #: ports/esp8266/modnetwork.c:142 msgid "Cannot set STA config" -msgstr "" +msgstr "No se puede establecer STA config" #: ports/esp8266/modnetwork.c:144 msgid "Cannot connect to AP" -msgstr "" +msgstr "No se puede conectar a AP" #: ports/esp8266/modnetwork.c:152 msgid "Cannot disconnect from AP" -msgstr "" +msgstr "No se puede desconectar de AP" #: ports/esp8266/modnetwork.c:173 msgid "unknown status param" -msgstr "" +msgstr "status param desconocido" #: ports/esp8266/modnetwork.c:222 msgid "STA must be active" -msgstr "" +msgstr "STA debe estar activo" #: ports/esp8266/modnetwork.c:239 msgid "scan failed" -msgstr "" +msgstr "scan ha fallado" #: ports/esp8266/modnetwork.c:306 msgid "wifi_set_ip_info() failed" -msgstr "" +msgstr "wifi_set_ip_info() ha fallado" #: ports/esp8266/modnetwork.c:319 msgid "either pos or kw args are allowed" -msgstr "" +msgstr "ya sea pos o kw args son permitidos" #: ports/esp8266/modnetwork.c:329 msgid "can't get STA config" -msgstr "" +msgstr "no se puede obtener STA config" #: ports/esp8266/modnetwork.c:331 msgid "can't get AP config" -msgstr "" +msgstr "no se puede obtener AP config" #: ports/esp8266/modnetwork.c:346 msgid "invalid buffer length" -msgstr "" +msgstr "longitud de buffer inválida" #: ports/esp8266/modnetwork.c:405 msgid "can't set STA config" -msgstr "" +msgstr "no se puede establecer STA config" #: ports/esp8266/modnetwork.c:407 msgid "can't set AP config" -msgstr "" +msgstr "no se puede establecer AP config" #: ports/esp8266/modnetwork.c:416 msgid "can query only one param" -msgstr "" +msgstr "puede consultar solo un param" #: ports/esp8266/modnetwork.c:469 msgid "unknown config param" -msgstr "" +msgstr "parámetro config desconocido" #: ports/nrf/common-hal/analogio/AnalogOut.c:37 msgid "AnalogOut functionality not supported" -- cgit v1.2.3 From aa95526428edb0196029587eb1b84fed544bbad8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 1 Oct 2018 18:54:13 -0400 Subject: nrf: remove error check for SPI baudrate too high; round to nearest baudrate --- locale/circuitpython.pot | 20 +++++-------- locale/de_DE.po | 20 +++++-------- locale/en_US.po | 20 +++++-------- locale/es.po | 23 +++++++-------- locale/fil.po | 20 +++++-------- locale/fr.po | 20 +++++-------- ports/nrf/common-hal/busio/SPI.c | 64 +++++++++++++++++++--------------------- shared-bindings/busio/SPI.c | 13 ++++++-- 8 files changed, 90 insertions(+), 110 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 513ec8efd..65f5caa75 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:52-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -361,7 +361,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "" @@ -690,18 +690,14 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -1990,19 +1986,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 72f7b254d..43b7076d6 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:44-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -370,7 +370,7 @@ msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Ungültige Pins" @@ -699,20 +699,16 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -2001,19 +1997,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index 63ae50ba5..fa60ee4fa 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:44-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -361,7 +361,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "" @@ -690,18 +690,14 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -1990,19 +1986,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" diff --git a/locale/es.po b/locale/es.po index 5120c74f2..1fb4c9e3b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:44-0400\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -376,7 +376,7 @@ msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "pines inválidos" @@ -620,7 +620,8 @@ msgstr "len debe de ser múltiple de 4" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "la asignación de memoria ha fallado, asignando %u bytes para código nativo" +msgstr "" +"la asignación de memoria ha fallado, asignando %u bytes para código nativo" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" @@ -706,18 +707,14 @@ msgstr "parámetro config desconocido" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -2033,19 +2030,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index ad6252a21..e41838757 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:44-0400\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -373,7 +373,7 @@ msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Mali ang pins" @@ -705,20 +705,16 @@ msgstr "hindi alam na config param" msgid "AnalogOut functionality not supported" msgstr "Hindi supportado ang AnalogOut" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -2030,19 +2026,19 @@ msgstr "Function nangangailangan ng lock" msgid "Buffer must be at least length 1" msgstr "Buffer dapat ay hindi baba sa 1 na haba" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "Mali ang polarity" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "Mali ang phase" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "Mali ang bilang ng bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "aarehas na haba dapat ang buffer slices" diff --git a/locale/fr.po b/locale/fr.po index d6d7b6087..9fb6ef71c 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"POT-Creation-Date: 2018-10-01 18:52-0400\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -368,7 +368,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Broche invalide" @@ -701,20 +701,16 @@ msgstr "paramètre de config. inconnu" msgid "AnalogOut functionality not supported" msgstr "AnalogOut non supporté" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:170 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 @@ -2021,19 +2017,19 @@ msgstr "La fonction nécessite un verrou" msgid "Buffer must be at least length 1" msgstr "Le tampon doit être de longueur au moins 1" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "Polarité invalide" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "Phase invalide" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "Nombre de bits invalide" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "les slices de tampon doivent être de longueurs égales" diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 54ae6e47c..8ff00d297 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -65,40 +65,40 @@ void spi_reset(void) { } } -// Convert frequency to clock-speed-dependent value +// Convert frequency to clock-speed-dependent value. Choose the nearest value, lower or higher. static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) { - if (baudrate <= 125000) { - return NRF_SPIM_FREQ_125K; - } - if (baudrate <= 250000) { - return NRF_SPIM_FREQ_250K; - } - if (baudrate <= 500000) { - return NRF_SPIM_FREQ_500K; - } - if (baudrate <= 1000000) { - return NRF_SPIM_FREQ_1M; - } - if (baudrate <= 2000000) { - return NRF_SPIM_FREQ_2M; - } - if (baudrate <= 4000000) { - return NRF_SPIM_FREQ_4M; - } - if (baudrate <= 8000000) { - return NRF_SPIM_FREQ_8M; - } -#ifdef SPIM_FREQUENCY_FREQUENCY_M16 - if (baudrate <= 16000000) { - return NRF_SPIM_FREQ_16M; - } -#endif + // Round requested baudrate to nearest available baudrate. + static const struct { + const uint32_t boundary; + nrf_spim_frequency_t spim_frequency; + } baudrate_map[] = { #ifdef SPIM_FREQUENCY_FREQUENCY_M32 - return NRF_SPIM_FREQ_32M; -#else - return NRF_SPIM_FREQ_8M; + { (16000000 + 32000000) / 2, NRF_SPIM_FREQ_32M }, +#endif +#ifdef SPIM_FREQUENCY_FREQUENCY_M16 + { ( 8000000 + 16000000) / 2, NRF_SPIM_FREQ_16M }, #endif + { ( 4000000 + 8000000) / 2, NRF_SPIM_FREQ_8M }, + { ( 2000000 + 4000000) / 2, NRF_SPIM_FREQ_4M }, + { ( 1000000 + 2000000) / 2, NRF_SPIM_FREQ_2M }, + { ( 500000 + 1000000) / 2, NRF_SPIM_FREQ_1M }, + { ( 250000 + 500000) / 2, NRF_SPIM_FREQ_500K }, + { ( 125000 + 250000) / 2, NRF_SPIM_FREQ_250K }, + { 0, NRF_SPIM_FREQ_125K }, + }; + + size_t i = 0; + uint32_t boundary; + do { + boundary = baudrate_map[i].boundary; + if (baudrate >= boundary) { + return baudrate_map[i].spim_frequency; + } + i++; + } while (boundary != 0); + // Will get here only if baudrate == 0. + return 0; } void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { @@ -172,10 +172,6 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, ui if (bits != 8) return false; - if (baudrate > self->spim_peripheral->max_frequency_MHz * 1000000) { - mp_raise_ValueError(translate("Baud rate too high for this SPI peripheral")); - return false; - } nrf_spim_frequency_set(self->spim_peripheral->spim.p_reg, baudrate_to_spim_frequency(baudrate)); nrf_spim_mode_t mode = NRF_SPIM_MODE_0; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 7983a3a56..be5f431ec 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -141,14 +141,21 @@ static void check_lock(busio_spi_obj_t *self) { //| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower //| due to the granularity of available clock settings. //| Check the `frequency` attribute for the actual clock rate. -//| **Note:** on the SAMD21, it is possible to set the baud rate to 24 MHz, but that -//| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is -//| within spec for the SAMD21. //| :param int polarity: the base state of the clock line (0 or 1) //| :param int phase: the edge of the clock that data is captured. First (0) //| or second (1). Rising or falling depends on clock polarity. //| :param int bits: the number of bits per word //| +//| .. note:: On the SAMD21, it is possible to set the baudrate to 24 MHz, but that +//| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is +//| within spec for the SAMD21. +//| +//| .. note:: On the nRF52832, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, +//| and 8MHz. On the nRF52840, 16MHz and 32MHz are also available, but only on the first +//| `busio.SPI` object you create. Two more ``busio.SPI`` objects can be created, but they are restricted +//| to 8MHz maximum. This is a hardware restriction: there is only one high-speed SPI peripheral. +//| If you pick a a baudrate other than one of these, the nearest available +//| baudrate will be chosen. STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; static const mp_arg_t allowed_args[] = { -- cgit v1.2.3 From 6c7195b1301cd6b23703547a5db3b57cd4982fb0 Mon Sep 17 00:00:00 2001 From: Lucas Furlaneto Date: Tue, 2 Oct 2018 01:15:13 -0300 Subject: Start Brazilian Portuguese translation --- locale/pt_BR.po | 2351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2351 insertions(+) create mode 100644 locale/pt_BR.po diff --git a/locale/pt_BR.po b/locale/pt_BR.po new file mode 100644 index 000000000..513ec8efd --- /dev/null +++ b/locale/pt_BR.po @@ -0,0 +1,2351 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-09-21 12:23-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: extmod/machine_i2c.c:299 +msgid "invalid I2C peripheral" +msgstr "" + +#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 +#: extmod/machine_i2c.c:392 +msgid "I2C operation not supported" +msgstr "" + +#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "" + +#: extmod/machine_spi.c:57 +msgid "invalid SPI peripheral" +msgstr "" + +#: extmod/machine_spi.c:124 +msgid "buffers must be the same length" +msgstr "" + +#: extmod/machine_spi.c:207 +msgid "bits must be 8" +msgstr "" + +#: extmod/machine_spi.c:210 +msgid "firstbit must be MSB" +msgstr "" + +#: extmod/machine_spi.c:215 +msgid "must specify all of sck/mosi/miso" +msgstr "" + +#: extmod/modframebuf.c:299 +msgid "invalid format" +msgstr "" + +#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 +msgid "a bytes-like object is required" +msgstr "" + +#: extmod/modubinascii.c:90 +msgid "odd-length string" +msgstr "" + +#: extmod/modubinascii.c:101 +msgid "non-hex digit found" +msgstr "" + +#: extmod/modubinascii.c:169 +msgid "incorrect padding" +msgstr "" + +#: extmod/moductypes.c:122 +msgid "syntax error in uctypes descriptor" +msgstr "" + +#: extmod/moductypes.c:219 +msgid "Cannot unambiguously get sizeof scalar" +msgstr "" + +#: extmod/moductypes.c:397 +msgid "struct: no fields" +msgstr "" + +#: extmod/moductypes.c:530 +msgid "struct: cannot index" +msgstr "" + +#: extmod/moductypes.c:544 +msgid "struct: index out of range" +msgstr "" + +#: extmod/moduheapq.c:38 +msgid "heap must be a list" +msgstr "" + +#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 +msgid "empty heap" +msgstr "" + +#: extmod/modujson.c:281 +msgid "syntax error in JSON" +msgstr "" + +#: extmod/modure.c:161 +msgid "Splitting with sub-captures" +msgstr "" + +#: extmod/modure.c:207 +msgid "Error in regex" +msgstr "" + +#: extmod/modussl_axtls.c:81 +msgid "invalid key" +msgstr "" + +#: extmod/modussl_axtls.c:87 +msgid "invalid cert" +msgstr "" + +#: extmod/modutimeq.c:131 +msgid "queue overflow" +msgstr "" + +#: extmod/moduzlib.c:98 +msgid "compression header" +msgstr "" + +#: extmod/uos_dupterm.c:120 +msgid "invalid dupterm index" +msgstr "" + +#: extmod/vfs_fat.c:426 py/moduerrno.c:150 +msgid "Read-only filesystem" +msgstr "" + +#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 +msgid "I/O operation on closed file" +msgstr "" + +#: lib/embed/abort_.c:8 +msgid "abort() called" +msgstr "" + +#: lib/netutils/netutils.c:83 +msgid "invalid arguments" +msgstr "" + +#: lib/utils/pyexec.c:97 py/builtinimport.c:253 +msgid "script compilation not supported" +msgstr "" + +#: main.c:143 +msgid " output:\n" +msgstr "" + +#: main.c:157 main.c:230 +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" + +#: main.c:159 +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "" + +#: main.c:161 main.c:232 +msgid "Auto-reload is off.\n" +msgstr "" + +#: main.c:175 +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" + +#: main.c:191 +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" + +#: main.c:239 +msgid "You requested starting safe mode by " +msgstr "" + +#: main.c:242 +msgid "To exit, please reset the board without " +msgstr "" + +#: main.c:249 +msgid "" +"You are running in safe mode which means something really bad happened.\n" +msgstr "" + +#: main.c:251 +msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +msgstr "" + +#: main.c:252 +msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" +msgstr "" + +#: main.c:255 +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +msgstr "" + +#: main.c:256 +msgid "" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" + +#: main.c:260 +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" + +#: main.c:416 +msgid "soft reboot\n" +msgstr "" + +#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 +msgid "All sync event channels in use" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c:135 +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c:137 +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 +msgid "No default I2C bus" +msgstr "" + +#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 +msgid "No default SPI bus" +msgstr "" + +#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 +msgid "No default UART bus" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 +#: ports/nrf/common-hal/analogio/AnalogIn.c:39 +msgid "Pin does not have ADC capabilities" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 +msgid "No DAC on chip" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 +msgid "AnalogOut not supported on given pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 +msgid "Invalid bit clock pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 +msgid "Bit clock and word select must share a clock unit" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 +msgid "Invalid data pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 +msgid "Serializer in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 +msgid "Clock unit in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 +msgid "Unable to find free GCLK" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 +msgid "Too many channels in sample." +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +msgid "No DMA channel found" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 +msgid "Invalid clock pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 +msgid "sampling rate out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +msgid "DAC already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +msgid "Right channel unsupported" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 +msgid "Invalid pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +msgid "Invalid pin for left channel" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +msgid "Invalid pin for right channel" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +msgid "Cannot output both channels on the same pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +msgid "All timers in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c:71 +msgid "Not enough pins available" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c:78 +#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/UART.c:119 +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 +#: ports/nrf/common-hal/busio/I2C.c:77 +msgid "Invalid pins" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c:101 +msgid "SDA or SCL needs a pull up" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c:121 +msgid "Unsupported baudrate" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:66 +msgid "bytes > 8 bits not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:72 +msgid "tx and rx cannot both be None" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:145 +msgid "Failed to allocate RX buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:153 +msgid "Could not initialize UART" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:240 +msgid "No RX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c:294 +msgid "No TX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 +#: ports/esp8266/common-hal/microcontroller/__init__.c:64 +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 +#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +msgid "Invalid PWM frequency" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 +msgid "All timers for this pin are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 +msgid "No hardware support on pin" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 +msgid "EXTINT channel already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +msgid "pop from an empty PulseIn" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 +msgid "index out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 +msgid "Another send is already active" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 +msgid "Both pins must support hardware interrupts" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 +msgid "A hardware interrupt channel is already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/rtc/RTC.c:101 +msgid "calibration value out of range +/-127" +msgstr "" + +#: ports/atmel-samd/common-hal/storage/__init__.c:48 +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 +msgid "No free GCLKs" +msgstr "" + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 +#: ports/nrf/common-hal/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 +#: ports/nrf/common-hal/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 +#: ports/nrf/common-hal/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" + +#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 +msgid "Pin %q does not have ADC capabilities" +msgstr "" + +#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 +msgid "No hardware support for analog out." +msgstr "" + +#: ports/esp8266/common-hal/busio/SPI.c:72 +msgid "Pins not valid for SPI" +msgstr "" + +#: ports/esp8266/common-hal/busio/UART.c:45 +msgid "Only tx supported on UART1 (GPIO2)." +msgstr "" + +#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 +msgid "invalid data bits" +msgstr "" + +#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 +msgid "invalid stop bits" +msgstr "" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 +msgid "ESP8266 does not support pull down." +msgstr "" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 +msgid "GPIO16 does not support pull up." +msgstr "" + +#: ports/esp8266/common-hal/microcontroller/__init__.c:66 +msgid "ESP8226 does not support safe mode." +msgstr "" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 +#, c-format +msgid "Maximum PWM frequency is %dhz." +msgstr "" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 +msgid "Minimum PWM frequency is 1hz." +msgstr "" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 +#, c-format +msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +msgstr "" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 +#, c-format +msgid "PWM not supported on pin %d" +msgstr "" + +#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 +msgid "No PulseIn support for %q" +msgstr "" + +#: ports/esp8266/common-hal/storage/__init__.c:34 +msgid "Unable to remount filesystem" +msgstr "" + +#: ports/esp8266/common-hal/storage/__init__.c:38 +msgid "Use esptool to erase flash and re-upload Python instead" +msgstr "" + +#: ports/esp8266/esp_mphal.c:154 +msgid "C-level assert" +msgstr "" + +#: ports/esp8266/machine_adc.c:57 +#, c-format +msgid "not a valid ADC Channel: %d" +msgstr "" + +#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 +msgid "impossible baudrate" +msgstr "" + +#: ports/esp8266/machine_pin.c:129 +msgid "expecting a pin" +msgstr "" + +#: ports/esp8266/machine_pin.c:284 +msgid "Pin(16) doesn't support pull" +msgstr "" + +#: ports/esp8266/machine_pin.c:323 +msgid "invalid pin" +msgstr "" + +#: ports/esp8266/machine_pin.c:389 +msgid "pin does not have IRQ capabilities" +msgstr "" + +#: ports/esp8266/machine_rtc.c:185 +msgid "buffer too long" +msgstr "" + +#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 +#: ports/esp8266/machine_rtc.c:246 +msgid "invalid alarm" +msgstr "" + +#: ports/esp8266/machine_uart.c:169 +#, c-format +msgid "UART(%d) does not exist" +msgstr "" + +#: ports/esp8266/machine_uart.c:219 +msgid "UART(1) can't read" +msgstr "" + +#: ports/esp8266/modesp.c:119 +msgid "len must be multiple of 4" +msgstr "" + +#: ports/esp8266/modesp.c:274 +#, c-format +msgid "memory allocation failed, allocating %u bytes for native code" +msgstr "" + +#: ports/esp8266/modesp.c:317 +msgid "flash location must be below 1MByte" +msgstr "" + +#: ports/esp8266/modmachine.c:63 +msgid "frequency can only be either 80Mhz or 160MHz" +msgstr "" + +#: ports/esp8266/modnetwork.c:61 +msgid "AP required" +msgstr "" + +#: ports/esp8266/modnetwork.c:61 +msgid "STA required" +msgstr "" + +#: ports/esp8266/modnetwork.c:87 +msgid "Cannot update i/f status" +msgstr "" + +#: ports/esp8266/modnetwork.c:142 +msgid "Cannot set STA config" +msgstr "" + +#: ports/esp8266/modnetwork.c:144 +msgid "Cannot connect to AP" +msgstr "" + +#: ports/esp8266/modnetwork.c:152 +msgid "Cannot disconnect from AP" +msgstr "" + +#: ports/esp8266/modnetwork.c:173 +msgid "unknown status param" +msgstr "" + +#: ports/esp8266/modnetwork.c:222 +msgid "STA must be active" +msgstr "" + +#: ports/esp8266/modnetwork.c:239 +msgid "scan failed" +msgstr "" + +#: ports/esp8266/modnetwork.c:306 +msgid "wifi_set_ip_info() failed" +msgstr "" + +#: ports/esp8266/modnetwork.c:319 +msgid "either pos or kw args are allowed" +msgstr "" + +#: ports/esp8266/modnetwork.c:329 +msgid "can't get STA config" +msgstr "" + +#: ports/esp8266/modnetwork.c:331 +msgid "can't get AP config" +msgstr "" + +#: ports/esp8266/modnetwork.c:346 +msgid "invalid buffer length" +msgstr "" + +#: ports/esp8266/modnetwork.c:405 +msgid "can't set STA config" +msgstr "" + +#: ports/esp8266/modnetwork.c:407 +msgid "can't set AP config" +msgstr "" + +#: ports/esp8266/modnetwork.c:416 +msgid "can query only one param" +msgstr "" + +#: ports/esp8266/modnetwork.c:469 +msgid "unknown config param" +msgstr "" + +#: ports/nrf/common-hal/analogio/AnalogOut.c:37 +msgid "AnalogOut functionality not supported" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c:91 +msgid "All I2C peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/SPI.c:109 +msgid "All SPI peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/SPI.c:170 +msgid "Baud rate too high for this SPI peripheral" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 +#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 +#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 +#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 +#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 +msgid "busio.UART not yet implemented" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:199 +msgid "Cannot apply GAP parameters." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:213 +msgid "Cannot set PPCP parameters." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:245 +msgid "Can not query for the device address." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:264 +msgid "Can not add Vendor Specific 128-bit UUID." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:284 +#: ports/nrf/drivers/bluetooth/ble_drv.c:298 +msgid "Can not add Service." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:373 +msgid "Can not add Characteristic." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:400 +msgid "Can not apply device name in the stack." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:464 +#: ports/nrf/drivers/bluetooth/ble_drv.c:514 +msgid "Can not encode UUID, to check length." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:470 +#: ports/nrf/drivers/bluetooth/ble_drv.c:520 +msgid "Can encode UUID into the advertisment packet." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:545 +msgid "Can not fit data into the advertisment packet." +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:558 +#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#, c-format +msgid "Can not apply advertisment data. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#, c-format +msgid "Can not start advertisment. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#, c-format +msgid "Can not stop advertisment. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:650 +#: ports/nrf/drivers/bluetooth/ble_drv.c:726 +#, c-format +msgid "Can not read attribute value. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:667 +#: ports/nrf/drivers/bluetooth/ble_drv.c:756 +#, c-format +msgid "Can not write attribute value. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:691 +#, c-format +msgid "Can not notify attribute value. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:784 +#, c-format +msgid "Can not start scanning. status: 0x%02x" +msgstr "" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#, c-format +msgid "Can not connect. status: 0x%02x" +msgstr "" + +#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 +#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 +#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 +#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 +msgid "Invalid UUID parameter" +msgstr "" + +#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 +msgid "Invalid Service type" +msgstr "" + +#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 +msgid "Invalid UUID string length" +msgstr "" + +#: ports/unix/modffi.c:138 +msgid "Unknown type" +msgstr "" + +#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 +msgid "Error in ffi_prep_cif" +msgstr "" + +#: ports/unix/modffi.c:270 +msgid "ffi_prep_closure_loc" +msgstr "" + +#: ports/unix/modffi.c:413 +msgid "Don't know how to pass object to native function" +msgstr "" + +#: ports/unix/modusocket.c:474 +#, c-format +msgid "[addrinfo error %d]" +msgstr "" + +#: py/argcheck.c:44 +msgid "function does not take keyword arguments" +msgstr "" + +#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" + +#: py/argcheck.c:64 +#, c-format +msgid "function missing %d required positional arguments" +msgstr "" + +#: py/argcheck.c:72 +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "" + +#: py/argcheck.c:97 +msgid "'%q' argument required" +msgstr "" + +#: py/argcheck.c:122 +msgid "extra positional arguments given" +msgstr "" + +#: py/argcheck.c:130 +msgid "extra keyword arguments given" +msgstr "" + +#: py/argcheck.c:142 +msgid "argument num/types mismatch" +msgstr "" + +#: py/argcheck.c:147 +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" + +#: py/bc.c:88 py/objnamedtuple.c:108 +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" + +#: py/bc.c:197 py/bc.c:215 +msgid "unexpected keyword argument" +msgstr "" + +#: py/bc.c:199 +msgid "keywords must be strings" +msgstr "" + +#: py/bc.c:206 py/objnamedtuple.c:138 +msgid "function got multiple values for argument '%q'" +msgstr "" + +#: py/bc.c:218 py/objnamedtuple.c:130 +msgid "unexpected keyword argument '%q'" +msgstr "" + +#: py/bc.c:244 +#, c-format +msgid "function missing required positional argument #%d" +msgstr "" + +#: py/bc.c:260 +msgid "function missing required keyword argument '%q'" +msgstr "" + +#: py/bc.c:269 +msgid "function missing keyword-only argument" +msgstr "" + +#: py/binary.c:112 +msgid "bad typecode" +msgstr "" + +#: py/builtinevex.c:99 +msgid "bad compile mode" +msgstr "" + +#: py/builtinimport.c:338 +msgid "cannot perform relative import" +msgstr "" + +#: py/builtinimport.c:422 py/builtinimport.c:534 +msgid "module not found" +msgstr "" + +#: py/builtinimport.c:425 py/builtinimport.c:537 +msgid "no module named '%q'" +msgstr "" + +#: py/builtinimport.c:512 +msgid "relative import" +msgstr "" + +#: py/compile.c:397 py/compile.c:542 +msgid "can't assign to expression" +msgstr "" + +#: py/compile.c:416 +msgid "multiple *x in assignment" +msgstr "" + +#: py/compile.c:642 +msgid "non-default argument follows default argument" +msgstr "" + +#: py/compile.c:771 py/compile.c:789 +msgid "invalid micropython decorator" +msgstr "" + +#: py/compile.c:943 +msgid "can't delete expression" +msgstr "" + +#: py/compile.c:955 +msgid "'break' outside loop" +msgstr "" + +#: py/compile.c:958 +msgid "'continue' outside loop" +msgstr "" + +#: py/compile.c:969 +msgid "'return' outside function" +msgstr "" + +#: py/compile.c:1169 +msgid "identifier redefined as global" +msgstr "" + +#: py/compile.c:1185 +msgid "no binding for nonlocal found" +msgstr "" + +#: py/compile.c:1188 +msgid "identifier redefined as nonlocal" +msgstr "" + +#: py/compile.c:1197 +msgid "can't declare nonlocal in outer code" +msgstr "" + +#: py/compile.c:1542 +msgid "default 'except' must be last" +msgstr "" + +#: py/compile.c:2095 +msgid "*x must be assignment target" +msgstr "" + +#: py/compile.c:2193 +msgid "super() can't find self" +msgstr "" + +#: py/compile.c:2256 +msgid "can't have multiple *x" +msgstr "" + +#: py/compile.c:2263 +msgid "can't have multiple **x" +msgstr "" + +#: py/compile.c:2271 +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: py/compile.c:2287 +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c:2291 +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 +#: py/parse.c:1176 +msgid "invalid syntax" +msgstr "" + +#: py/compile.c:2465 +msgid "expecting key:value for dict" +msgstr "" + +#: py/compile.c:2475 +msgid "expecting just a value for set" +msgstr "" + +#: py/compile.c:2600 +msgid "'yield' outside function" +msgstr "" + +#: py/compile.c:2619 +msgid "'await' outside function" +msgstr "" + +#: py/compile.c:2774 +msgid "name reused for argument" +msgstr "" + +#: py/compile.c:2827 +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/compile.c:2969 py/compile.c:3137 +msgid "return annotation must be an identifier" +msgstr "" + +#: py/compile.c:3097 +msgid "inline assembler must be a function" +msgstr "" + +#: py/compile.c:3134 +msgid "unknown type" +msgstr "" + +#: py/compile.c:3154 +msgid "expecting an assembler instruction" +msgstr "" + +#: py/compile.c:3184 +msgid "'label' requires 1 argument" +msgstr "" + +#: py/compile.c:3190 +msgid "label redefined" +msgstr "" + +#: py/compile.c:3196 +msgid "'align' requires 1 argument" +msgstr "" + +#: py/compile.c:3205 +msgid "'data' requires at least 2 arguments" +msgstr "" + +#: py/compile.c:3212 +msgid "'data' requires integer arguments" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:162 +#, c-format +msgid "'%s' expects a register" +msgstr "" + +#: py/emitinlinextensa.c:169 +#, c-format +msgid "'%s' expects an integer" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinextensa.c:182 +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinextensa.c:193 +msgid "label '%q' not defined" +msgstr "" + +#: py/emitinlinextensa.c:327 +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/emitnative.c:183 +msgid "unknown type '%q'" +msgstr "" + +#: py/emitnative.c:260 +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: py/emitnative.c:742 +msgid "conversion to object" +msgstr "" + +#: py/emitnative.c:921 +msgid "local '%q' used before type known" +msgstr "" + +#: py/emitnative.c:1118 py/emitnative.c:1156 +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c:1128 +msgid "can't load with '%q' index" +msgstr "" + +#: py/emitnative.c:1188 +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c:1289 py/emitnative.c:1379 +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c:1358 py/emitnative.c:1419 +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c:1369 +msgid "can't store with '%q' index" +msgstr "" + +#: py/emitnative.c:1540 +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c:1774 +msgid "unary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1930 +msgid "binary op %q not implemented" +msgstr "" + +#: py/emitnative.c:1951 +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/emitnative.c:2126 +msgid "casting" +msgstr "" + +#: py/emitnative.c:2173 +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/emitnative.c:2191 +msgid "must raise an object" +msgstr "" + +#: py/emitnative.c:2201 +msgid "native yield" +msgstr "" + +#: py/lexer.c:345 +msgid "unicode name escapes" +msgstr "" + +#: py/modbuiltins.c:162 +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c:171 +msgid "chr() arg not in range(256)" +msgstr "" + +#: py/modbuiltins.c:285 +msgid "arg is an empty sequence" +msgstr "" + +#: py/modbuiltins.c:350 +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c:353 +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/modbuiltins.c:363 +msgid "3-arg pow() not supported" +msgstr "" + +#: py/modbuiltins.c:517 +msgid "must use keyword argument for key function" +msgstr "" + +#: py/modmath.c:41 shared-bindings/math/__init__.c:53 +msgid "math domain error" +msgstr "" + +#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 +#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 +msgid "division by zero" +msgstr "" + +#: py/modmicropython.c:155 +msgid "schedule stack full" +msgstr "" + +#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 +#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 +#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +msgid "buffer too small" +msgstr "" + +#: py/modthread.c:240 +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/moduerrno.c:143 py/moduerrno.c:146 +msgid "Permission denied" +msgstr "" + +#: py/moduerrno.c:144 +msgid "No such file/directory" +msgstr "" + +#: py/moduerrno.c:145 +msgid "Input/output error" +msgstr "" + +#: py/moduerrno.c:147 +msgid "File exists" +msgstr "" + +#: py/moduerrno.c:148 +msgid "Unsupported operation" +msgstr "" + +#: py/moduerrno.c:149 +msgid "Invalid argument" +msgstr "" + +#: py/obj.c:90 +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: py/obj.c:94 +msgid " File \"%q\", line %d" +msgstr "" + +#: py/obj.c:96 +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c:100 +msgid ", in %q\n" +msgstr "" + +#: py/obj.c:257 +msgid "can't convert to int" +msgstr "" + +#: py/obj.c:260 +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/obj.c:320 +msgid "can't convert to float" +msgstr "" + +#: py/obj.c:323 +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c:353 +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c:356 +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c:371 +msgid "expected tuple/list" +msgstr "" + +#: py/obj.c:374 +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c:385 +msgid "tuple/list has wrong length" +msgstr "" + +#: py/obj.c:387 +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/obj.c:400 +msgid "indices must be integers" +msgstr "" + +#: py/obj.c:403 +msgid "%q indices must be integers, not %s" +msgstr "" + +#: py/obj.c:423 +msgid "%q index out of range" +msgstr "" + +#: py/obj.c:455 +msgid "object has no len" +msgstr "" + +#: py/obj.c:458 +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c:496 +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c:499 +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/obj.c:503 +msgid "object is not subscriptable" +msgstr "" + +#: py/obj.c:506 +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/obj.c:510 +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c:513 +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c:544 +msgid "object with buffer protocol required" +msgstr "" + +#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 +#: shared-bindings/nvm/ByteArray.c:85 +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/objarray.c:426 +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 +msgid "array/bytes required on right side" +msgstr "" + +#: py/objcomplex.c:203 +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/objcomplex.c:209 +msgid "complex division by zero" +msgstr "" + +#: py/objcomplex.c:237 +msgid "0.0 to a complex power" +msgstr "" + +#: py/objdeque.c:107 +msgid "full" +msgstr "" + +#: py/objdeque.c:127 +msgid "empty" +msgstr "" + +#: py/objdict.c:314 +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objdict.c:357 +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/objfloat.c:308 py/parsenum.c:331 +msgid "complex values not supported" +msgstr "" + +#: py/objgenerator.c:108 +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objgenerator.c:126 +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c:229 +msgid "generator ignored GeneratorExit" +msgstr "" + +#: py/objgenerator.c:251 +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objint.c:144 +msgid "can't convert inf to int" +msgstr "" + +#: py/objint.c:146 +msgid "can't convert NaN to int" +msgstr "" + +#: py/objint.c:163 +msgid "float too big" +msgstr "" + +#: py/objint.c:328 +msgid "long int not supported in this build" +msgstr "" + +#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 +msgid "small int overflow" +msgstr "" + +#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 +msgid "negative power with no float support" +msgstr "" + +#: py/objint_longlong.c:251 +msgid "ulonglong too large" +msgstr "" + +#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 +msgid "negative shift count" +msgstr "" + +#: py/objint_mpz.c:336 +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: py/objint_mpz.c:347 +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c:415 +msgid "overflow converting long int to machine word" +msgstr "" + +#: py/objlist.c:273 +msgid "pop from empty list" +msgstr "" + +#: py/objnamedtuple.c:92 +msgid "can't set attribute" +msgstr "" + +#: py/objobject.c:55 +msgid "__new__ arg must be a user-type" +msgstr "" + +#: py/objrange.c:110 +msgid "zero step" +msgstr "" + +#: py/objset.c:371 +msgid "pop from an empty set" +msgstr "" + +#: py/objslice.c:66 +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c:71 +msgid "Length must be non-negative" +msgstr "" + +#: py/objslice.c:86 py/sequence.c:57 +msgid "slice step cannot be zero" +msgstr "" + +#: py/objslice.c:159 +msgid "Cannot subclass slice" +msgstr "" + +#: py/objstr.c:261 +msgid "bytes value out of range" +msgstr "" + +#: py/objstr.c:270 +msgid "wrong number of arguments" +msgstr "" + +#: py/objstr.c:467 +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 +msgid "empty separator" +msgstr "" + +#: py/objstr.c:641 +msgid "rsplit(None,n)" +msgstr "" + +#: py/objstr.c:713 +msgid "substring not found" +msgstr "" + +#: py/objstr.c:770 +msgid "start/end indices" +msgstr "" + +#: py/objstr.c:931 +msgid "bad format string" +msgstr "" + +#: py/objstr.c:953 +msgid "single '}' encountered in format string" +msgstr "" + +#: py/objstr.c:992 +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c:996 +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: py/objstr.c:998 +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c:1029 +msgid "unmatched '{' in format" +msgstr "" + +#: py/objstr.c:1036 +msgid "expected ':' after format specifier" +msgstr "" + +#: py/objstr.c:1050 +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c:1055 py/objstr.c:1083 +msgid "tuple index out of range" +msgstr "" + +#: py/objstr.c:1071 +msgid "attributes not supported yet" +msgstr "" + +#: py/objstr.c:1079 +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objstr.c:1171 +msgid "invalid format specifier" +msgstr "" + +#: py/objstr.c:1192 +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1200 +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c:1259 +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c:1331 +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c:1343 +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1367 +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/objstr.c:1415 +msgid "format requires a dict" +msgstr "" + +#: py/objstr.c:1424 +msgid "incomplete format key" +msgstr "" + +#: py/objstr.c:1482 +msgid "incomplete format" +msgstr "" + +#: py/objstr.c:1490 +msgid "not enough arguments for format string" +msgstr "" + +#: py/objstr.c:1500 +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: py/objstr.c:1507 +msgid "integer required" +msgstr "" + +#: py/objstr.c:1570 +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/objstr.c:1577 +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c:2102 +msgid "can't convert to str implicitly" +msgstr "" + +#: py/objstr.c:2106 +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objstrunicode.c:134 +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/objstrunicode.c:145 py/objstrunicode.c:164 +msgid "string index out of range" +msgstr "" + +#: py/objtype.c:358 +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c:360 +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +msgid "unreadable attribute" +msgstr "" + +#: py/objtype.c:868 py/runtime.c:653 +msgid "object not callable" +msgstr "" + +#: py/objtype.c:870 py/runtime.c:655 +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/objtype.c:978 +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objtype.c:989 +msgid "cannot create instance" +msgstr "" + +#: py/objtype.c:991 +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c:1047 +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c:1091 py/objtype.c:1097 +msgid "type is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1100 +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c:1137 +msgid "multiple inheritance not supported" +msgstr "" + +#: py/objtype.c:1164 +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c:1205 +msgid "first argument to super() must be type" +msgstr "" + +#: py/objtype.c:1370 +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objtype.c:1384 +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/parse.c:726 +msgid "constant must be an integer" +msgstr "" + +#: py/parse.c:868 +msgid "Unable to init parser" +msgstr "" + +#: py/parse.c:1170 +msgid "unexpected indent" +msgstr "" + +#: py/parse.c:1173 +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/parsenum.c:60 +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/parsenum.c:151 +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c:155 +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c:339 +msgid "invalid syntax for number" +msgstr "" + +#: py/parsenum.c:342 +msgid "decimal numbers not supported" +msgstr "" + +#: py/persistentcode.c:223 +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: py/persistentcode.c:326 +msgid "can only save bytecode" +msgstr "" + +#: py/runtime.c:206 +msgid "name not defined" +msgstr "" + +#: py/runtime.c:209 +msgid "name '%q' is not defined" +msgstr "" + +#: py/runtime.c:304 py/runtime.c:611 +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c:307 +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c:614 +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 +msgid "wrong number of values to unpack" +msgstr "" + +#: py/runtime.c:883 py/runtime.c:947 +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/runtime.c:890 +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/runtime.c:984 +msgid "argument has wrong type" +msgstr "" + +#: py/runtime.c:986 +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/runtime.c:1123 py/runtime.c:1197 +msgid "no such attribute" +msgstr "" + +#: py/runtime.c:1128 +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1132 py/runtime.c:1200 +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c:1238 +msgid "object not iterable" +msgstr "" + +#: py/runtime.c:1241 +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/runtime.c:1260 py/runtime.c:1296 +msgid "object not an iterator" +msgstr "" + +#: py/runtime.c:1262 py/runtime.c:1298 +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/runtime.c:1401 +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/runtime.c:1430 +msgid "cannot import name %q" +msgstr "" + +#: py/runtime.c:1535 +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/runtime.c:1539 +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c:1609 +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/sequence.c:264 +msgid "object not in sequence" +msgstr "" + +#: py/stream.c:96 +msgid "stream operation not supported" +msgstr "" + +#: py/vm.c:255 +msgid "local variable referenced before assignment" +msgstr "" + +#: py/vm.c:1142 +msgid "no active exception to reraise" +msgstr "" + +#: py/vm.c:1284 +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_stage/Layer.c:71 +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/_stage/Layer.c:84 +msgid "map buffer too small" +msgstr "" + +#: shared-bindings/_stage/Text.c:69 +msgid "font must be 2048 bytes long" +msgstr "" + +#: shared-bindings/_stage/Text.c:81 +msgid "chars buffer too small" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c:118 +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c:225 +#: shared-bindings/audioio/AudioOut.c:223 +msgid "Not playing" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:124 +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:128 +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:136 +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:193 +msgid "destination_length must be an int >= 0" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:199 +msgid "Cannot record to a file" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:202 +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:206 +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c:208 +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:98 +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: shared-bindings/audioio/RawSample.c:104 +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-bindings/audioio/WaveFile.c:78 +#: shared-bindings/displayio/OnDiskBitmap.c:85 +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 +#: shared-bindings/busio/SPI.c:133 +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +msgid "Buffer must be at least length 1" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +msgid "Invalid phase" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +msgid "buffer slices must be of equal length" +msgstr "" + +#: shared-bindings/busio/I2C.c:120 +msgid "Function requires lock." +msgstr "" + +#: shared-bindings/busio/UART.c:102 +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: shared-bindings/busio/UART.c:114 +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:211 +msgid "Invalid direction." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:240 +msgid "Cannot set value when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:266 +#: shared-bindings/digitalio/DigitalInOut.c:281 +msgid "Drive mode not used when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:314 +#: shared-bindings/digitalio/DigitalInOut.c:331 +msgid "Pull not used when direction is output." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:340 +msgid "Unsupported pull value." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:84 +msgid "y should be an int" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:89 +msgid "row buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c:94 +msgid "row data must be a buffer" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c:72 +msgid "color should be an int" +msgstr "" + +#: shared-bindings/displayio/FourWire.c:55 +#: shared-bindings/displayio/FourWire.c:64 +msgid "displayio is a work in progress" +msgstr "" + +#: shared-bindings/displayio/Group.c:65 +msgid "Group must have size at least 1" +msgstr "" + +#: shared-bindings/displayio/Palette.c:96 +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c:102 +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c:106 +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/Palette.c:110 +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c:123 +#: shared-bindings/displayio/Palette.c:137 +msgid "palette_index should be an int" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:48 +msgid "position must be 2-tuple" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:97 +msgid "unsupported bitmap type" +msgstr "" + +#: shared-bindings/displayio/Sprite.c:162 +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:100 +msgid "too many arguments" +msgstr "" + +#: shared-bindings/gamepad/GamePad.c:104 +msgid "expected a DigitalInOut" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:98 +msgid "can't convert address to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:101 +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c:107 +msgid "addresses is empty" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:89 +#: shared-bindings/neopixel_write/__init__.c:67 +#: shared-bindings/pulseio/PulseOut.c:75 +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c:100 +msgid "%q in use" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c:126 +msgid "Invalid run mode." +msgstr "" + +#: shared-bindings/multiterminal/__init__.c:68 +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:99 +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:104 +msgid "Array values should be single bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 +msgid "Unable to write to nvm." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:137 +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: shared-bindings/os/__init__.c:200 +msgid "No hardware random available" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:164 +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c:195 +msgid "" +"PWM frequency not writeable when variable_frequency is False on construction." +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:275 +msgid "Cannot delete values" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:281 +msgid "Slices not supported" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:287 +msgid "index must be int" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c:293 +msgid "Read-only" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c:134 +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 +msgid "stop not reachable from start" +msgstr "" + +#: shared-bindings/random/__init__.c:111 +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/random/__init__.c:114 +msgid "invalid step" +msgstr "" + +#: shared-bindings/random/__init__.c:146 +msgid "empty sequence" +msgstr "" + +#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 +#: shared-bindings/time/__init__.c:190 +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/rtc/RTC.c:52 +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/storage/__init__.c:77 +msgid "filesystem must provide mount method" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:93 +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/supervisor/__init__.c:119 +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/time/__init__.c:78 +msgid "sleep length must be non-negative" +msgstr "" + +#: shared-bindings/time/__init__.c:88 +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/time/__init__.c:91 +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:250 +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:255 +msgid "function takes exactly 9 arguments" +msgstr "" + +#: shared-bindings/time/__init__.c:226 shared-bindings/time/__init__.c:259 +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c:173 +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/util.c:38 +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: shared-module/audioio/WaveFile.c:61 +msgid "Invalid wave file" +msgstr "" + +#: shared-module/audioio/WaveFile.c:69 +msgid "Invalid format chunk size" +msgstr "" + +#: shared-module/audioio/WaveFile.c:83 +msgid "Unsupported format" +msgstr "" + +#: shared-module/audioio/WaveFile.c:99 +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: shared-module/audioio/WaveFile.c:107 +msgid "Invalid file" +msgstr "" + +#: shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/bitbangio/I2C.c:58 +msgid "Clock stretch too long" +msgstr "" + +#: shared-module/bitbangio/SPI.c:45 +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:51 +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:62 +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c:122 +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:177 +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-module/bitbangio/SPI.c:241 +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: shared-module/displayio/Bitmap.c:49 +msgid "Only bit maps of 8 bit color or less are supported" +msgstr "" + +#: shared-module/displayio/Bitmap.c:69 +msgid "row must be packed and word aligned" +msgstr "" + +#: shared-module/displayio/Group.c:39 +msgid "Group full" +msgstr "" + +#: shared-module/displayio/Group.c:48 +msgid "Group empty" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:49 +msgid "Invalid BMP file" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:59 +#, c-format +msgid "Only Windows format, uncompressed BMP supported %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c:64 +#, c-format +msgid "Only true color (24 bpp or higher) BMP supported %x" +msgstr "" + +#: shared-module/struct/__init__.c:39 +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: shared-module/struct/__init__.c:83 +msgid "too many arguments provided with the given format" +msgstr "" -- cgit v1.2.3 From 5cfd28b78a4c81e34fe69f3746f4e30e374665e3 Mon Sep 17 00:00:00 2001 From: Lucas Furlaneto Date: Tue, 2 Oct 2018 01:36:24 -0300 Subject: Update pt_BR.po --- locale/pt_BR.po | 68 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 513ec8efd..d73cf0d9e 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,52 +8,52 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 12:23-0400\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" +"POT-Creation-Date: 2018-10-02 01:19-0300\n" +"PO-Revision-Date: 2018-10-02 01:19-0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: extmod/machine_i2c.c:299 msgid "invalid I2C peripheral" -msgstr "" +msgstr "periférico I2C inválido" #: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 #: extmod/machine_i2c.c:392 msgid "I2C operation not supported" -msgstr "" +msgstr "I2C operação não suportada" #: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 #, c-format msgid "address %08x is not aligned to %d bytes" -msgstr "" +msgstr "endereço %08x não está alinhado com %d bytes" #: extmod/machine_spi.c:57 msgid "invalid SPI peripheral" -msgstr "" +msgstr "periférico SPI inválido" #: extmod/machine_spi.c:124 msgid "buffers must be the same length" -msgstr "" +msgstr "buffers devem ser o mesmo tamanho" #: extmod/machine_spi.c:207 msgid "bits must be 8" -msgstr "" +msgstr "bits devem ser 8" #: extmod/machine_spi.c:210 msgid "firstbit must be MSB" -msgstr "" +msgstr "firstbit devem ser MSB" #: extmod/machine_spi.c:215 msgid "must specify all of sck/mosi/miso" -msgstr "" +msgstr "deve especificar todos sck/mosi/miso" #: extmod/modframebuf.c:299 msgid "invalid format" -msgstr "" +msgstr "formato inválido" #: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 msgid "a bytes-like object is required" @@ -69,7 +69,7 @@ msgstr "" #: extmod/modubinascii.c:169 msgid "incorrect padding" -msgstr "" +msgstr "preenchimento incorreto" #: extmod/moductypes.c:122 msgid "syntax error in uctypes descriptor" @@ -81,27 +81,27 @@ msgstr "" #: extmod/moductypes.c:397 msgid "struct: no fields" -msgstr "" +msgstr "struct: sem campos" #: extmod/moductypes.c:530 msgid "struct: cannot index" -msgstr "" +msgstr "struct: não pode indexar" #: extmod/moductypes.c:544 msgid "struct: index out of range" -msgstr "" +msgstr "struct: índice fora do intervalo" #: extmod/moduheapq.c:38 msgid "heap must be a list" -msgstr "" +msgstr "heap deve ser uma lista" #: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 msgid "empty heap" -msgstr "" +msgstr "heap vazia" #: extmod/modujson.c:281 msgid "syntax error in JSON" -msgstr "" +msgstr "erro de sintaxe no JSON" #: extmod/modure.c:161 msgid "Splitting with sub-captures" @@ -109,19 +109,19 @@ msgstr "" #: extmod/modure.c:207 msgid "Error in regex" -msgstr "" +msgstr "Erro no regex" #: extmod/modussl_axtls.c:81 msgid "invalid key" -msgstr "" +msgstr "chave inválida" #: extmod/modussl_axtls.c:87 msgid "invalid cert" -msgstr "" +msgstr "certificado inválido" #: extmod/modutimeq.c:131 msgid "queue overflow" -msgstr "" +msgstr "estouro de fila" #: extmod/moduzlib.c:98 msgid "compression header" @@ -133,27 +133,27 @@ msgstr "" #: extmod/vfs_fat.c:426 py/moduerrno.c:150 msgid "Read-only filesystem" -msgstr "" +msgstr "Sistema de arquivos somente leitura" #: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 msgid "I/O operation on closed file" -msgstr "" +msgstr "Operação I/O no arquivo fechado" #: lib/embed/abort_.c:8 msgid "abort() called" -msgstr "" +msgstr "abort() chamado" #: lib/netutils/netutils.c:83 msgid "invalid arguments" -msgstr "" +msgstr "argumentos inválidos" #: lib/utils/pyexec.c:97 py/builtinimport.c:253 msgid "script compilation not supported" -msgstr "" +msgstr "compilação de script não suportada" #: main.c:143 msgid " output:\n" -msgstr "" +msgstr " saída:\n" #: main.c:157 main.c:230 msgid "" @@ -163,15 +163,15 @@ msgstr "" #: main.c:159 msgid "Running in safe mode! Auto-reload is off.\n" -msgstr "" +msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" #: main.c:161 main.c:232 msgid "Auto-reload is off.\n" -msgstr "" +msgstr "A atualização automática está desligada.\n" #: main.c:175 msgid "Running in safe mode! Not running saved code.\n" -msgstr "" +msgstr "Rodando em modo seguro! Não está executando o código salvo." #: main.c:191 msgid "WARNING: Your code filename has two extensions\n" -- cgit v1.2.3 From cc68964d1372570eb456c4891b4acfa3261ace75 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 1 Oct 2018 22:20:27 -0700 Subject: Fix the build --- locale/pt_BR.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index d73cf0d9e..21debc359 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -14,7 +14,7 @@ msgstr "" "Language-Team: \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: extmod/machine_i2c.c:299 @@ -171,7 +171,7 @@ msgstr "A atualização automática está desligada.\n" #: main.c:175 msgid "Running in safe mode! Not running saved code.\n" -msgstr "Rodando em modo seguro! Não está executando o código salvo." +msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" #: main.c:191 msgid "WARNING: Your code filename has two extensions\n" -- cgit v1.2.3 From 3c743f2664abc7bfd18eaa6705bbaf5c18576a9f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 2 Oct 2018 11:56:09 -0700 Subject: Update Trellis M4 Express for Rev C --- .../boards/trellis_m4_express/mpconfigboard.h | 4 ++-- ports/atmel-samd/external_flash/devices.h | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h index 117a8ae8e..fbc5300e2 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -3,7 +3,7 @@ #define CIRCUITPY_MCU_FAMILY samd51 -// This is for Rev A +// This is for a purple prototype which is Rev C #define MICROPY_HW_APA102_MOSI (&pin_PA01) #define MICROPY_HW_APA102_SCK (&pin_PA00) @@ -28,7 +28,7 @@ #include "external_flash/devices.h" #define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_DEVICES W25Q128JV_SQ #include "external_flash/external_flash.h" diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h index ea1b24a32..974936419 100644 --- a/ports/atmel-samd/external_flash/devices.h +++ b/ports/atmel-samd/external_flash/devices.h @@ -266,5 +266,23 @@ typedef struct { } +// Settings for the Winbond W25Q128JV-SQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_SQ {\ + .total_size = (1 << 23), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + + #endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H -- cgit v1.2.3 From 21d331c8cc54855897549ebcbcf9983235d98b2e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 2 Oct 2018 21:06:40 -0400 Subject: round SPI freq down; check max freq --- ports/nrf/common-hal/busio/SPI.c | 50 ++++++++++++++++++++++------------------ shared-bindings/busio/SPI.c | 6 ++--- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 8ff00d297..405d19c23 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -65,27 +65,27 @@ void spi_reset(void) { } } -// Convert frequency to clock-speed-dependent value. Choose the nearest value, lower or higher. +// Convert frequency to clock-speed-dependent value. Choose the next lower baudrate if in between +// available baudrates. static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) { - // Round requested baudrate to nearest available baudrate. static const struct { const uint32_t boundary; nrf_spim_frequency_t spim_frequency; } baudrate_map[] = { #ifdef SPIM_FREQUENCY_FREQUENCY_M32 - { (16000000 + 32000000) / 2, NRF_SPIM_FREQ_32M }, + { 32000000, NRF_SPIM_FREQ_32M }, #endif #ifdef SPIM_FREQUENCY_FREQUENCY_M16 - { ( 8000000 + 16000000) / 2, NRF_SPIM_FREQ_16M }, + { 16000000, NRF_SPIM_FREQ_16M }, #endif - { ( 4000000 + 8000000) / 2, NRF_SPIM_FREQ_8M }, - { ( 2000000 + 4000000) / 2, NRF_SPIM_FREQ_4M }, - { ( 1000000 + 2000000) / 2, NRF_SPIM_FREQ_2M }, - { ( 500000 + 1000000) / 2, NRF_SPIM_FREQ_1M }, - { ( 250000 + 500000) / 2, NRF_SPIM_FREQ_500K }, - { ( 125000 + 250000) / 2, NRF_SPIM_FREQ_250K }, - { 0, NRF_SPIM_FREQ_125K }, + { 8000000, NRF_SPIM_FREQ_8M }, + { 4000000, NRF_SPIM_FREQ_4M }, + { 2000000, NRF_SPIM_FREQ_2M }, + { 1000000, NRF_SPIM_FREQ_1M }, + { 500000, NRF_SPIM_FREQ_500K }, + { 250000, NRF_SPIM_FREQ_250K }, + { 0, NRF_SPIM_FREQ_125K }, }; size_t i = 0; @@ -97,7 +97,7 @@ static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) } i++; } while (boundary != 0); - // Will get here only if baudrate == 0. + // Should not get here. return 0; } @@ -168,22 +168,26 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - // nrf52 does not support 16 bit - if (bits != 8) + // nrf52 does not support 16 bit + if (bits != 8) { return false; + } - nrf_spim_frequency_set(self->spim_peripheral->spim.p_reg, baudrate_to_spim_frequency(baudrate)); + // Set desired frequency, rounding down, and don't go above available frequency for this SPIM. + nrf_spim_frequency_set(self->spim_peripheral->spim.p_reg, + baudrate_to_spim_frequency(MIN(baudrate, + self->spim_peripheral->max_frequency_MHz * 1000000))); - nrf_spim_mode_t mode = NRF_SPIM_MODE_0; - if (polarity) { - mode = (phase) ? NRF_SPIM_MODE_3 : NRF_SPIM_MODE_2; - } else { - mode = (phase) ? NRF_SPIM_MODE_1 : NRF_SPIM_MODE_0; - } + nrf_spim_mode_t mode = NRF_SPIM_MODE_0; + if (polarity) { + mode = (phase) ? NRF_SPIM_MODE_3 : NRF_SPIM_MODE_2; + } else { + mode = (phase) ? NRF_SPIM_MODE_1 : NRF_SPIM_MODE_0; + } - nrf_spim_configure(self->spim_peripheral->spim.p_reg, mode, NRF_SPIM_BIT_ORDER_MSB_FIRST); + nrf_spim_configure(self->spim_peripheral->spim.p_reg, mode, NRF_SPIM_BIT_ORDER_MSB_FIRST); - return true; + return true; } bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index be5f431ec..d30bbbe06 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -136,7 +136,7 @@ static void check_lock(busio_spi_obj_t *self) { //| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8) //| -//| Configures the SPI bus. Only valid when locked. +//| Configures the SPI bus. The SPI object must be locked. //| //| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower //| due to the granularity of available clock settings. @@ -154,8 +154,8 @@ static void check_lock(busio_spi_obj_t *self) { //| and 8MHz. On the nRF52840, 16MHz and 32MHz are also available, but only on the first //| `busio.SPI` object you create. Two more ``busio.SPI`` objects can be created, but they are restricted //| to 8MHz maximum. This is a hardware restriction: there is only one high-speed SPI peripheral. -//| If you pick a a baudrate other than one of these, the nearest available -//| baudrate will be chosen. +//| If you pick a a baudrate other than one of these, the nearest lower +//| baudrate will be chosen, with a minimum of 125kHz. STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; static const mp_arg_t allowed_args[] = { -- cgit v1.2.3 From 1d287d066b792481d90df7fabccd3e06e137ce76 Mon Sep 17 00:00:00 2001 From: Gabriel Vasconcelos Date: Tue, 2 Oct 2018 22:16:37 -0300 Subject: Added new portuguese translations --- locale/pt_BR.po | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 21debc359..1d114bce1 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -2249,103 +2249,103 @@ msgstr "" #: shared-bindings/touchio/TouchIn.c:173 msgid "threshold must be in the range 0-65536" -msgstr "" +msgstr "Limite deve estar no alcance de 0-65536" #: shared-bindings/util.c:38 msgid "" "Object has been deinitialized and can no longer be used. Create a new object." -msgstr "" +msgstr "Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" -msgstr "" +msgstr "Aqruivo de ondas inválido" #: shared-module/audioio/WaveFile.c:69 msgid "Invalid format chunk size" -msgstr "" +msgstr "Tamanho do pedaço de formato inválido" #: shared-module/audioio/WaveFile.c:83 msgid "Unsupported format" -msgstr "" +msgstr "Formato não suportado" #: shared-module/audioio/WaveFile.c:99 msgid "Data chunk must follow fmt chunk" -msgstr "" +msgstr "Pedaço de dados deve seguir o pedaço de cortes" #: shared-module/audioio/WaveFile.c:107 msgid "Invalid file" -msgstr "" +msgstr "Arquivo inválido" #: shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" -msgstr "" +msgstr "Não pôde alocar primeiro buffer" #: shared-module/audioio/WaveFile.c:123 msgid "Couldn't allocate second buffer" -msgstr "" +msgstr "Não pôde alocar segundo buffer" #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" -msgstr "" +msgstr "Clock se estendeu por tempo demais" #: shared-module/bitbangio/SPI.c:45 msgid "Clock pin init failed." -msgstr "" +msgstr "Inicialização do pino de Clock falhou." #: shared-module/bitbangio/SPI.c:51 msgid "MOSI pin init failed." -msgstr "" +msgstr "Inicialização do pino MOSI falhou." #: shared-module/bitbangio/SPI.c:62 msgid "MISO pin init failed." -msgstr "" +msgstr "Inicialização do pino MISO falhou" #: shared-module/bitbangio/SPI.c:122 msgid "Cannot write without MOSI pin." -msgstr "" +msgstr "Não é possível ler sem um pino MOSI" #: shared-module/bitbangio/SPI.c:177 msgid "Cannot read without MISO pin." -msgstr "" +msgstr "Não é possível ler sem o pino MISO." #: shared-module/bitbangio/SPI.c:241 msgid "Cannot transfer without MOSI and MISO pins." -msgstr "" +msgstr "Não é possível transferir sem os pinos MOSI e MISO." #: shared-module/displayio/Bitmap.c:49 msgid "Only bit maps of 8 bit color or less are supported" -msgstr "" +msgstr "Apenas bit maps de cores de 8 bit ou menos são suportados" #: shared-module/displayio/Bitmap.c:69 msgid "row must be packed and word aligned" -msgstr "" +msgstr "Linha deve ser comprimida e com as palavras alinhadas" #: shared-module/displayio/Group.c:39 msgid "Group full" -msgstr "" +msgstr "Grupo cheio" #: shared-module/displayio/Group.c:48 msgid "Group empty" -msgstr "" +msgstr "Grupo vazio" #: shared-module/displayio/OnDiskBitmap.c:49 msgid "Invalid BMP file" -msgstr "" +msgstr "Arquivo BMP inválido" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format msgid "Only Windows format, uncompressed BMP supported %d" -msgstr "" +msgstr "Apenas formato Windows, BMP descomprimido suportado" #: shared-module/displayio/OnDiskBitmap.c:64 #, c-format msgid "Only true color (24 bpp or higher) BMP supported %x" -msgstr "" +msgstr "Apenas cores verdadeiras (24 bpp ou maior) BMP suportadas" #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" -msgstr "" +msgstr "'S' e 'O' não são tipos de formato suportados" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" -msgstr "" +msgstr "Muitos argumentos fornecidos com o formato dado" -- cgit v1.2.3 From ddd2a90eeef0fa98f8cc1385932a68d644257e64 Mon Sep 17 00:00:00 2001 From: Pedro Filipe Date: Tue, 2 Oct 2018 21:38:25 -0300 Subject: String internationalization for Brazilian Portuguese --- locale/pt_BR.po | 124 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 21debc359..3b2b16ba8 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-10-02 01:19-0300\n" -"PO-Revision-Date: 2018-10-02 01:19-0300\n" +"PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" "Language: pt_BR\n" @@ -129,7 +129,7 @@ msgstr "" #: extmod/uos_dupterm.c:120 msgid "invalid dupterm index" -msgstr "" +msgstr "Índice de dupterm inválido" #: extmod/vfs_fat.c:426 py/moduerrno.c:150 msgid "Read-only filesystem" @@ -175,15 +175,15 @@ msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" #: main.c:191 msgid "WARNING: Your code filename has two extensions\n" -msgstr "" +msgstr "AVISO: Seu arquivo de código tem duas extensões\n" #: main.c:239 msgid "You requested starting safe mode by " -msgstr "" +msgstr "Você solicitou o início do modo de segurança" #: main.c:242 msgid "To exit, please reset the board without " -msgstr "" +msgstr "Para sair, por favor, reinicie a placa sem " #: main.c:249 msgid "" @@ -225,41 +225,41 @@ msgstr "" #: ports/atmel-samd/bindings/samd/Clock.c:135 msgid "calibration is read only" -msgstr "" +msgstr "Calibração é somente leitura" #: ports/atmel-samd/bindings/samd/Clock.c:137 msgid "calibration is out of range" -msgstr "" +msgstr "Calibração está fora do intervalo" #: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 msgid "No default I2C bus" -msgstr "" +msgstr "Nenhum barramento I2C padrão" #: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 msgid "No default SPI bus" -msgstr "" +msgstr "Nenhum barramento SPI padrão" #: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 msgid "No default UART bus" -msgstr "" +msgstr "Nenhum barramento UART padrão" #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" -msgstr "" +msgstr "O pino não tem recursos de ADC" #: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 msgid "No DAC on chip" -msgstr "" +msgstr "Nenhum DAC no chip" #: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 msgid "AnalogOut not supported on given pin" -msgstr "" +msgstr "Saída analógica não suportada no pino fornecido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 msgid "Invalid bit clock pin" -msgstr "" +msgstr "Pino de bit clock inválido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 msgid "Bit clock and word select must share a clock unit" @@ -268,41 +268,41 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 msgid "Invalid data pin" -msgstr "" +msgstr "Pino de dados inválido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 msgid "Serializer in use" -msgstr "" +msgstr "Serializer em uso" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 msgid "Clock unit in use" -msgstr "" +msgstr "Unidade de Clock em uso" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 msgid "Unable to find free GCLK" -msgstr "" +msgstr "Não é possível encontrar GCLK livre" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 msgid "Too many channels in sample." -msgstr "" +msgstr "Muitos canais na amostra." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 #: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 msgid "No DMA channel found" -msgstr "" +msgstr "Nenhum canal DMA encontrado" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 #: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 msgid "Unable to allocate buffers for signed conversion" -msgstr "" +msgstr "Não é possível alocar buffers para conversão assinada" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 msgid "Invalid clock pin" -msgstr "" +msgstr "Pino do Clock inválido" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 msgid "Only 8 or 16 bit mono with " @@ -310,29 +310,29 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 msgid "sampling rate out of range" -msgstr "" +msgstr "Taxa de amostragem fora do intervalo" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 msgid "DAC already in use" -msgstr "" +msgstr "DAC em uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 msgid "Right channel unsupported" -msgstr "" +msgstr "Canal direito não suportado" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" -msgstr "" +msgstr "Pino inválido" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 msgid "Invalid pin for left channel" -msgstr "" +msgstr "Pino inválido para canal esquerdo" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 msgid "Invalid pin for right channel" -msgstr "" +msgstr "Pino inválido para canal direito" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 msgid "Cannot output both channels on the same pin" @@ -342,20 +342,20 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 msgid "All timers in use" -msgstr "" +msgstr "Todos os temporizadores em uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 msgid "All event channels in use" -msgstr "" +msgstr "Todos os canais de eventos em uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "" +msgstr "Taxa de amostragem muito alta. Deve ser menor que %d" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" -msgstr "" +msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/I2C.c:78 #: ports/atmel-samd/common-hal/busio/SPI.c:132 @@ -363,39 +363,39 @@ msgstr "" #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:77 msgid "Invalid pins" -msgstr "" +msgstr "Pinos inválidos" #: ports/atmel-samd/common-hal/busio/I2C.c:101 msgid "SDA or SCL needs a pull up" -msgstr "" +msgstr "SDA ou SCL precisa de um pull up" #: ports/atmel-samd/common-hal/busio/I2C.c:121 msgid "Unsupported baudrate" -msgstr "" +msgstr "Taxa de transmissão não suportada" #: ports/atmel-samd/common-hal/busio/UART.c:66 msgid "bytes > 8 bits not supported" -msgstr "" +msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:72 msgid "tx and rx cannot both be None" -msgstr "" +msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:145 msgid "Failed to allocate RX buffer" -msgstr "" +msgstr "Falha ao alocar buffer RX" #: ports/atmel-samd/common-hal/busio/UART.c:153 msgid "Could not initialize UART" -msgstr "" +msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:240 msgid "No RX pin" -msgstr "" +msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:294 msgid "No TX pin" -msgstr "" +msgstr "Nenhum pino TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 #: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 @@ -411,25 +411,25 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 #: ports/nrf/common-hal/pulseio/PWMOut.c:227 msgid "Invalid PWM frequency" -msgstr "" +msgstr "Frequência PWM inválida" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 msgid "All timers for this pin are in use" -msgstr "" +msgstr "Todos os temporizadores para este pino estão em uso" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 msgid "No hardware support on pin" -msgstr "" +msgstr "Nenhum suporte de hardware no pino" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 msgid "EXTINT channel already in use" -msgstr "" +msgstr "Canal EXTINT em uso" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 #, c-format msgid "Failed to allocate RX buffer of %d bytes" -msgstr "" +msgstr "Falha ao alocar buffer RX de %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 @@ -439,71 +439,71 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 #: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 msgid "index out of range" -msgstr "" +msgstr "Índice fora do intervalo" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 msgid "Another send is already active" -msgstr "" +msgstr "Outro envio já está ativo" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 msgid "Both pins must support hardware interrupts" -msgstr "" +msgstr "Ambos os pinos devem suportar interrupções de hardware" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 msgid "A hardware interrupt channel is already in use" -msgstr "" +msgstr "Um canal de interrupção de hardware já está em uso" #: ports/atmel-samd/common-hal/rtc/RTC.c:101 msgid "calibration value out of range +/-127" -msgstr "" +msgstr "Valor de calibração fora do intervalo +/- 127" #: ports/atmel-samd/common-hal/storage/__init__.c:48 msgid "Cannot remount '/' when USB is active." -msgstr "" +msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" -msgstr "" +msgstr "Não há GCLKs livre" #: ports/atmel-samd/common-hal/usb_hid/Device.c:78 #: ports/nrf/common-hal/usb_hid/Device.c:45 #, c-format msgid "Buffer incorrect size. Should be %d bytes." -msgstr "" +msgstr "Buffer de tamanho incorreto. Deve ser %d bytes." #: ports/atmel-samd/common-hal/usb_hid/Device.c:82 #: ports/nrf/common-hal/usb_hid/Device.c:53 msgid "USB Busy" -msgstr "" +msgstr "USB ocupada" #: ports/atmel-samd/common-hal/usb_hid/Device.c:82 #: ports/nrf/common-hal/usb_hid/Device.c:59 msgid "USB Error" -msgstr "" +msgstr "Erro na USB" #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" -msgstr "" +msgstr "Pino %q não tem recursos de ADC" #: ports/esp8266/common-hal/analogio/AnalogOut.c:39 msgid "No hardware support for analog out." -msgstr "" +msgstr "Nenhum suporte de hardware para saída analógica." #: ports/esp8266/common-hal/busio/SPI.c:72 msgid "Pins not valid for SPI" -msgstr "" +msgstr "Pinos não válidos para SPI" #: ports/esp8266/common-hal/busio/UART.c:45 msgid "Only tx supported on UART1 (GPIO2)." -msgstr "" +msgstr "Apenas TX suportado no UART1 (GPIO2)." #: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 msgid "invalid data bits" -msgstr "" +msgstr "Bits de dados inválidos" #: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 msgid "invalid stop bits" -msgstr "" +msgstr "Bits de parada inválidos" #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 msgid "ESP8266 does not support pull down." -- cgit v1.2.3 From 67d9aef4c719b4b665807a92556b0c6a08a7deff Mon Sep 17 00:00:00 2001 From: Lucas Furlaneto Date: Wed, 3 Oct 2018 01:01:11 -0300 Subject: Update pt_BR.po --- locale/pt_BR.po | 106 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 9a93a52c5..3c4692a09 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -1227,7 +1227,7 @@ msgstr "" #: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 #: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 msgid "division by zero" -msgstr "" +msgstr "divisão por zero" #: py/modmicropython.c:155 msgid "schedule stack full" @@ -1245,7 +1245,7 @@ msgstr "" #: py/moduerrno.c:143 py/moduerrno.c:146 msgid "Permission denied" -msgstr "" +msgstr "Permissão negada" #: py/moduerrno.c:144 msgid "No such file/directory" @@ -1257,7 +1257,7 @@ msgstr "" #: py/moduerrno.c:147 msgid "File exists" -msgstr "" +msgstr "Arquivo já existe" #: py/moduerrno.c:148 msgid "Unsupported operation" @@ -1265,7 +1265,7 @@ msgstr "" #: py/moduerrno.c:149 msgid "Invalid argument" -msgstr "" +msgstr "Argumento inválido" #: py/obj.c:90 msgid "Traceback (most recent call last):\n" @@ -1273,11 +1273,11 @@ msgstr "" #: py/obj.c:94 msgid " File \"%q\", line %d" -msgstr "" +msgstr " Arquivo \"%q\", linha %d" #: py/obj.c:96 msgid " File \"%q\"" -msgstr "" +msgstr " Arquivo \"%q\"" #: py/obj.c:100 msgid ", in %q\n" @@ -1407,11 +1407,11 @@ msgstr "" #: py/objdeque.c:107 msgid "full" -msgstr "" +msgstr "cheio" #: py/objdeque.c:127 msgid "empty" -msgstr "" +msgstr "vazio" #: py/objdict.c:314 msgid "popitem(): dictionary is empty" @@ -1451,7 +1451,7 @@ msgstr "" #: py/objint.c:163 msgid "float too big" -msgstr "" +msgstr "float muito grande" #: py/objint.c:328 msgid "long int not supported in this build" @@ -1499,7 +1499,7 @@ msgstr "" #: py/objrange.c:110 msgid "zero step" -msgstr "" +msgstr "passo zero" #: py/objset.c:371 msgid "pop from an empty set" @@ -1507,7 +1507,7 @@ msgstr "" #: py/objslice.c:66 msgid "Length must be an int" -msgstr "" +msgstr "Tamanho deve ser um int" #: py/objslice.c:71 msgid "Length must be non-negative" @@ -1589,7 +1589,7 @@ msgstr "" #: py/objstr.c:1071 msgid "attributes not supported yet" -msgstr "" +msgstr "atributos ainda não suportados" #: py/objstr.c:1079 msgid "" @@ -1637,7 +1637,7 @@ msgstr "" #: py/objstr.c:1482 msgid "incomplete format" -msgstr "" +msgstr "formato incompleto" #: py/objstr.c:1490 msgid "not enough arguments for format string" @@ -1646,11 +1646,11 @@ msgstr "" #: py/objstr.c:1500 #, c-format msgid "%%c requires int or char" -msgstr "" +msgstr "%%c requer int ou char" #: py/objstr.c:1507 msgid "integer required" -msgstr "" +msgstr "inteiro requerido" #: py/objstr.c:1570 #, c-format @@ -1689,7 +1689,7 @@ msgstr "" #: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 msgid "unreadable attribute" -msgstr "" +msgstr "atributo ilegível" #: py/objtype.c:868 py/runtime.c:653 msgid "object not callable" @@ -1706,7 +1706,7 @@ msgstr "" #: py/objtype.c:989 msgid "cannot create instance" -msgstr "" +msgstr "não é possível criar instância" #: py/objtype.c:991 msgid "cannot create '%q' instances" @@ -1746,7 +1746,7 @@ msgstr "" #: py/parse.c:726 msgid "constant must be an integer" -msgstr "" +msgstr "constante deve ser um inteiro" #: py/parse.c:868 msgid "Unable to init parser" @@ -1793,7 +1793,7 @@ msgstr "" #: py/runtime.c:206 msgid "name not defined" -msgstr "" +msgstr "nome não definido" #: py/runtime.c:209 msgid "name '%q' is not defined" @@ -1818,7 +1818,7 @@ msgstr "" #: py/runtime.c:883 py/runtime.c:947 #, c-format msgid "need more than %d values to unpack" -msgstr "" +msgstr "precisa de mais de %d valores para desempacotar" #: py/runtime.c:890 #, c-format @@ -1827,7 +1827,7 @@ msgstr "" #: py/runtime.c:984 msgid "argument has wrong type" -msgstr "" +msgstr "argumento tem tipo errado" #: py/runtime.c:986 msgid "argument should be a '%q' not a '%q'" @@ -1847,7 +1847,7 @@ msgstr "" #: py/runtime.c:1238 msgid "object not iterable" -msgstr "" +msgstr "objeto não iterável" #: py/runtime.c:1241 #, c-format @@ -1869,7 +1869,7 @@ msgstr "" #: py/runtime.c:1430 msgid "cannot import name %q" -msgstr "" +msgstr "não pode importar nome %q" #: py/runtime.c:1535 msgid "memory allocation failed, heap is locked" @@ -1886,7 +1886,7 @@ msgstr "" #: py/sequence.c:264 msgid "object not in sequence" -msgstr "" +msgstr "objeto não em seqüência" #: py/stream.c:96 msgid "stream operation not supported" @@ -1947,11 +1947,11 @@ msgstr "" #: shared-bindings/audiobusio/PDMIn.c:193 msgid "destination_length must be an int >= 0" -msgstr "" +msgstr "destination_length deve ser um int >= 0" #: shared-bindings/audiobusio/PDMIn.c:199 msgid "Cannot record to a file" -msgstr "" +msgstr "Não é possível gravar em um arquivo" #: shared-bindings/audiobusio/PDMIn.c:202 msgid "Destination capacity is smaller than destination_length." @@ -1996,11 +1996,11 @@ msgstr "" #: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 msgid "Invalid phase" -msgstr "" +msgstr "Fase Inválida" #: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 msgid "Invalid number of bits" -msgstr "" +msgstr "Número inválido de bits" #: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 msgid "buffer slices must be of equal length" @@ -2020,7 +2020,7 @@ msgstr "" #: shared-bindings/digitalio/DigitalInOut.c:211 msgid "Invalid direction." -msgstr "" +msgstr "Direção inválida" #: shared-bindings/digitalio/DigitalInOut.c:240 msgid "Cannot set value when direction is input." @@ -2042,7 +2042,7 @@ msgstr "" #: shared-bindings/displayio/Bitmap.c:84 msgid "y should be an int" -msgstr "" +msgstr "y deve ser um int" #: shared-bindings/displayio/Bitmap.c:89 msgid "row buffer must be a bytearray or array of type 'b' or 'B'" @@ -2054,7 +2054,7 @@ msgstr "" #: shared-bindings/displayio/ColorConverter.c:72 msgid "color should be an int" -msgstr "" +msgstr "cor deve ser um int" #: shared-bindings/displayio/FourWire.c:55 #: shared-bindings/displayio/FourWire.c:64 @@ -2063,7 +2063,7 @@ msgstr "" #: shared-bindings/displayio/Group.c:65 msgid "Group must have size at least 1" -msgstr "" +msgstr "Grupo deve ter tamanho pelo menos 1" #: shared-bindings/displayio/Palette.c:96 msgid "color buffer must be a bytearray or array of type 'b' or 'B'" @@ -2075,7 +2075,7 @@ msgstr "" #: shared-bindings/displayio/Palette.c:106 msgid "color must be between 0x000000 and 0xffffff" -msgstr "" +msgstr "cor deve estar entre 0x000000 e 0xffffff" #: shared-bindings/displayio/Palette.c:110 msgid "color buffer must be a buffer or int" @@ -2100,7 +2100,7 @@ msgstr "" #: shared-bindings/gamepad/GamePad.c:100 msgid "too many arguments" -msgstr "" +msgstr "muitos argumentos" #: shared-bindings/gamepad/GamePad.c:104 msgid "expected a DigitalInOut" @@ -2122,11 +2122,11 @@ msgstr "" #: shared-bindings/neopixel_write/__init__.c:67 #: shared-bindings/pulseio/PulseOut.c:75 msgid "Expected a %q" -msgstr "" +msgstr "Esperado um" #: shared-bindings/microcontroller/Pin.c:100 msgid "%q in use" -msgstr "" +msgstr "%q em uso" #: shared-bindings/microcontroller/__init__.c:126 msgid "Invalid run mode." @@ -2146,11 +2146,11 @@ msgstr "" #: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 msgid "Unable to write to nvm." -msgstr "" +msgstr "Não é possível gravar no nvm." #: shared-bindings/nvm/ByteArray.c:137 msgid "Bytes must be between 0 and 255." -msgstr "" +msgstr "Os bytes devem estar entre 0 e 255." #: shared-bindings/os/__init__.c:200 msgid "No hardware random available" @@ -2168,7 +2168,7 @@ msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 msgid "Cannot delete values" -msgstr "" +msgstr "Não é possível excluir valores" #: shared-bindings/pulseio/PulseIn.c:281 msgid "Slices not supported" @@ -2176,15 +2176,15 @@ msgstr "" #: shared-bindings/pulseio/PulseIn.c:287 msgid "index must be int" -msgstr "" +msgstr "index deve ser int" #: shared-bindings/pulseio/PulseIn.c:293 msgid "Read-only" -msgstr "" +msgstr "Somente leitura" #: shared-bindings/pulseio/PulseOut.c:134 msgid "Array must contain halfwords (type 'H')" -msgstr "" +msgstr "Array deve conter meias palavras (tipo 'H')" #: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 msgid "stop not reachable from start" @@ -2192,36 +2192,36 @@ msgstr "" #: shared-bindings/random/__init__.c:111 msgid "step must be non-zero" -msgstr "" +msgstr "o passo deve ser diferente de zero" #: shared-bindings/random/__init__.c:114 msgid "invalid step" -msgstr "" +msgstr "passo inválido" #: shared-bindings/random/__init__.c:146 msgid "empty sequence" -msgstr "" +msgstr "seqüência vazia" #: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 #: shared-bindings/time/__init__.c:190 msgid "RTC is not supported on this board" -msgstr "" +msgstr "O RTC não é suportado nesta placa" #: shared-bindings/rtc/RTC.c:52 msgid "RTC calibration is not supported on this board" -msgstr "" +msgstr "A calibração RTC não é suportada nesta placa" #: shared-bindings/storage/__init__.c:77 msgid "filesystem must provide mount method" -msgstr "" +msgstr "sistema de arquivos deve fornecer método de montagem" #: shared-bindings/supervisor/__init__.c:93 msgid "Brightness must be between 0 and 255" -msgstr "" +msgstr "O brilho deve estar entre 0 e 255" #: shared-bindings/supervisor/__init__.c:119 msgid "Stack size must be at least 256" -msgstr "" +msgstr "O tamanho da pilha deve ser pelo menos 256" #: shared-bindings/time/__init__.c:78 msgid "sleep length must be non-negative" @@ -2237,15 +2237,15 @@ msgstr "" #: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:250 msgid "Tuple or struct_time argument required" -msgstr "" +msgstr "Tuple or struct_time argument required" #: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:255 msgid "function takes exactly 9 arguments" -msgstr "" +msgstr "função leva exatamente 9 argumentos" #: shared-bindings/time/__init__.c:226 shared-bindings/time/__init__.c:259 msgid "timestamp out of range for platform time_t" -msgstr "" +msgstr "timestamp fora do intervalo para a plataforma time_t" #: shared-bindings/touchio/TouchIn.c:173 msgid "threshold must be in the range 0-65536" -- cgit v1.2.3 From f543c8415d96aff96b252a0256795e1eb874f2ed Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Oct 2018 11:30:31 +0700 Subject: "busio.UART not yet implemented -> not available --- locale/circuitpython.pot | 14 +++++++------- locale/de_DE.po | 14 +++++++------- locale/en_US.po | 14 +++++++------- locale/es.po | 14 +++++++------- locale/fil.po | 15 ++++++++------- locale/fr.po | 23 ++++++++++++----------- ports/nrf/common-hal/busio/UART.c | 20 ++++++++++---------- 7 files changed, 58 insertions(+), 56 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 05cb73287..c224b9d6a 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -719,12 +719,12 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +msgid "busio.UART not available" msgstr "" #: ports/nrf/common-hal/microcontroller/Processor.c:49 diff --git a/locale/de_DE.po b/locale/de_DE.po index 098e065d0..b60d644f9 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -732,12 +732,12 @@ msgstr "ungültiger dupterm index" msgid "Odd parity is not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +msgid "busio.UART not available" msgstr "" #: ports/nrf/common-hal/microcontroller/Processor.c:49 diff --git a/locale/en_US.po b/locale/en_US.po index c57949b67..255de333d 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -719,12 +719,12 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +msgid "busio.UART not available" msgstr "" #: ports/nrf/common-hal/microcontroller/Processor.c:49 diff --git a/locale/es.po b/locale/es.po index 9d8f057be..c3c87bf46 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -737,12 +737,12 @@ msgstr "index dupterm inválido" msgid "Odd parity is not supported" msgstr "bytes > 8 bits no son soportados" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +msgid "busio.UART not available" msgstr "" #: ports/nrf/common-hal/microcontroller/Processor.c:49 diff --git a/locale/fil.po b/locale/fil.po index 6223463da..e131a5c62 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -738,12 +738,13 @@ msgstr "mali ang buffer length" msgid "Odd parity is not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +#, fuzzy +msgid "busio.UART not available" msgstr "hindi pa implemented ang busio.UART" #: ports/nrf/common-hal/microcontroller/Processor.c:49 diff --git a/locale/fr.po b/locale/fr.po index 3b3baca84..9bd874e5c 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-26 02:09+0700\n" +"POT-Creation-Date: 2018-10-03 11:28+0700\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -734,12 +734,13 @@ msgstr "longueur de tampon invalide" msgid "Odd parity is not supported" msgstr "octets > 8 bits non supporté" -#: ports/nrf/common-hal/busio/UART.c:245 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:326 ports/nrf/common-hal/busio/UART.c:331 -#: ports/nrf/common-hal/busio/UART.c:336 ports/nrf/common-hal/busio/UART.c:342 -#: ports/nrf/common-hal/busio/UART.c:347 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:356 ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 +#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 +#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 +#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 +#: ports/nrf/common-hal/busio/UART.c:360 +#, fuzzy +msgid "busio.UART not available" msgstr "busio.UART pas encore implémenté" #: ports/nrf/common-hal/microcontroller/Processor.c:49 @@ -2424,10 +2425,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "'len' doit être un multiple de 4" - #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "la palette doit être longue de 32 octets" + +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "'len' doit être un multiple de 4" diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index d3bd2a854..8d0db34be 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -190,7 +190,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t } // Write characters. -size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { +size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { if ( nrf_uarte_tx_pin_get(self->uarte.p_reg) == NRF_UARTE_PSEL_DISCONNECTED ) { mp_raise_ValueError(translate("No TX pin")); } @@ -315,41 +315,41 @@ void common_hal_busio_uart_construct (busio_uart_obj_t *self, const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, uint8_t receiver_buffer_size) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); } bool common_hal_busio_uart_deinited (busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); return true; } void common_hal_busio_uart_deinit (busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); } // Read characters. size_t common_hal_busio_uart_read (busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); return 0; } // Write characters. size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); return 0; } uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); return self->baudrate; } void common_hal_busio_uart_set_baudrate (busio_uart_obj_t *self, uint32_t baudrate) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); } uint32_t common_hal_busio_uart_rx_characters_available (busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); } void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t *self) { @@ -357,7 +357,7 @@ void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t *self) { } bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t *self) { - mp_raise_NotImplementedError(translate("busio.UART not yet implemented")); + mp_raise_NotImplementedError(translate("busio.UART not available")); return false; } #endif -- cgit v1.2.3 From 08cbb03bddfa1a18ac8048e979fb2e9682beb1c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Oct 2018 11:39:01 +0700 Subject: implement common_hal_busio_uart_clear_rx_buffer --- ports/nrf/common-hal/busio/UART.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 8d0db34be..b2dbb56a1 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -250,7 +250,11 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { } void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { - + // Discard received byte, and queue 1-byte transfer for rx_characters_available() + if ( self->rx_count > 0 ) { + self->rx_count = -1; + _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, 1)); + } } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { -- cgit v1.2.3 From 4b9099358f3f0041b54148c8004af4e788c4e37e Mon Sep 17 00:00:00 2001 From: Enrico Paganin Date: Wed, 3 Oct 2018 09:56:30 +0200 Subject: Fix 'advertisement' typo --- locale/circuitpython.pot | 10 +++++----- locale/de_DE.po | 10 +++++----- locale/en_US.po | 10 +++++----- locale/es.po | 10 +++++----- locale/fil.po | 14 +++++++------- locale/fr.po | 10 +++++----- locale/pt_BR.po | 10 +++++----- ports/nrf/drivers/bluetooth/ble_drv.c | 16 ++++++++-------- ports/nrf/examples/ubluepy_eddystone.py | 2 +- ports/nrf/examples/ubluepy_temp.py | 2 +- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 4 ++-- 11 files changed, 49 insertions(+), 49 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 513ec8efd..0a0e18361 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -751,27 +751,27 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/locale/de_DE.po b/locale/de_DE.po index 72f7b254d..b0fac6bc8 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -762,27 +762,27 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/locale/en_US.po b/locale/en_US.po index 63ae50ba5..6c6816edc 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -751,27 +751,27 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/locale/es.po b/locale/es.po index 5120c74f2..5cf8c28a8 100644 --- a/locale/es.po +++ b/locale/es.po @@ -767,27 +767,27 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/locale/fil.po b/locale/fil.po index ad6252a21..e5d19c8ee 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -768,28 +768,28 @@ msgstr "Hindi ma-encode UUID, para suriin ang haba." #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "Maaring i-encode ang UUID sa advertisement packet." #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "Hindi makasya ang data sa loob ng advertisement packet." #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" -msgstr "Hindi ma i-apply ang advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" +msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "Hindi masimulaan ang advertisement. status 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" -msgstr "Hindi mahinto ang advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" +msgstr "Hindi mahinto ang advertisement. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 #: ports/nrf/drivers/bluetooth/ble_drv.c:726 diff --git a/locale/fr.po b/locale/fr.po index d6d7b6087..bb908b8c3 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -764,27 +764,27 @@ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 21debc359..ab21628cf 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -751,27 +751,27 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisment packet." +msgid "Can encode UUID into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisment packet." +msgid "Can not fit data into the advertisement packet." msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format -msgid "Can not apply advertisment data. status: 0x%02x" +msgid "Can not apply advertisement data. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format -msgid "Can not start advertisment. status: 0x%02x" +msgid "Can not start advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format -msgid "Can not stop advertisment. status: 0x%02x" +msgid "Can not stop advertisement. status: 0x%02x" msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 7e95c2eab..3f21f8c49 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -467,7 +467,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { // do encoding into the adv buffer if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisment packet."))); + translate("Can encode UUID into the advertisement packet."))); } BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); @@ -517,7 +517,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { // do encoding into the adv buffer if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisment packet."))); + translate("Can encode UUID into the advertisement packet."))); } BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); @@ -542,7 +542,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) { if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not fit data into the advertisment packet."))); + translate("Can not fit data into the advertisement packet."))); } memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len); @@ -555,7 +555,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisment data. status: 0x%02x"), (uint16_t)err_code)); + translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); } BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos); #endif @@ -586,7 +586,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS; #else m_adv_params.fp = BLE_GAP_ADV_FP_ANY; - m_adv_params.timeout = 0; // infinite advertisment + m_adv_params.timeout = 0; // infinite advertisement #endif ble_drv_advertise_stop(); @@ -601,7 +601,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisment data. status: 0x%02x"), (uint16_t)err_code)); + translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); } err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT); #elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4) @@ -611,7 +611,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { #endif if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not start advertisment. status: 0x%02x"), (uint16_t)err_code)); + translate("Can not start advertisement. status: 0x%02x"), (uint16_t)err_code)); } m_adv_in_progress = true; @@ -628,7 +628,7 @@ void ble_drv_advertise_stop(void) { if ((err_code = sd_ble_gap_adv_stop()) != 0) { #endif nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not stop advertisment. status: 0x%02x"), (uint16_t)err_code)); + translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code)); } } m_adv_in_progress = false; diff --git a/ports/nrf/examples/ubluepy_eddystone.py b/ports/nrf/examples/ubluepy_eddystone.py index c8abd5aea..baf25ba4b 100644 --- a/ports/nrf/examples/ubluepy_eddystone.py +++ b/ports/nrf/examples/ubluepy_eddystone.py @@ -44,7 +44,7 @@ def generate_eddystone_adv_packet(url): service_data = uuid + eddystone_data packet_service_data = gen_ad_type_content(constants.ad_types.AD_TYPE_SERVICE_DATA, service_data) - # generate advertisment packet + # generate advertisement packet packet = bytearray([]) packet.extend(packet_flags) packet.extend(packet_uuid16) diff --git a/ports/nrf/examples/ubluepy_temp.py b/ports/nrf/examples/ubluepy_temp.py index fac091bc1..e5c157dbb 100644 --- a/ports/nrf/examples/ubluepy_temp.py +++ b/ports/nrf/examples/ubluepy_temp.py @@ -41,7 +41,7 @@ def event_handler(id, handle, data): rtc.stop() # indicate 'disconnected' LED(1).off() - # restart advertisment + # restart advertisement periph.advertise(device_name="micr_temp", services=[serv_env_sense]) elif id == constants.EVT_GATTS_WRITE: diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 48e467374..7b6b315a9 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -166,7 +166,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_conn_handler_obj, periph #if MICROPY_PY_UBLUEPY_PERIPHERAL /// \method advertise(device_name, [service=[service1, service2, ...]], [data=bytearray], [connectable=True]) -/// Start advertising. Connectable advertisment type by default. +/// Start advertising. Connectable advertisement type by default. /// STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { @@ -236,7 +236,7 @@ STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_advertise_obj, 0, peripheral_advertise); /// \method advertise_stop() -/// Stop advertisment if any onging advertisment. +/// Stop advertisement if any onging advertisement. /// STATIC mp_obj_t peripheral_advertise_stop(mp_obj_t self_in) { ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); -- cgit v1.2.3 From a47eaa521b39f90667da17a4ec7a1c256dec2ab5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Oct 2018 23:16:02 +0700 Subject: update translate --- locale/circuitpython.pot | 20 ++++++++++---------- locale/de_DE.po | 20 ++++++++++---------- locale/en_US.po | 20 ++++++++++---------- locale/es.po | 23 ++++++++++++----------- locale/fil.po | 20 ++++++++++---------- locale/fr.po | 28 ++++++++++++++-------------- locale/pt_BR.po | 44 ++++++++++++++++++++++++++++++++------------ 7 files changed, 98 insertions(+), 77 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0d6a612b8..ca8d55dcb 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -361,7 +361,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "" @@ -694,15 +694,15 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -719,11 +719,11 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not available" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index defe320ca..4579f8c67 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -370,7 +370,7 @@ msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Ungültige Pins" @@ -703,17 +703,17 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -732,11 +732,11 @@ msgstr "ungültiger dupterm index" msgid "Odd parity is not supported" msgstr "bytes mit merh als 8 bits werden nicht unterstützt" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not available" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index a05a3c028..1a120e668 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -361,7 +361,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "" @@ -694,15 +694,15 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -719,11 +719,11 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not available" msgstr "" diff --git a/locale/es.po b/locale/es.po index 5d3aee77f..664fd9be7 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -376,7 +376,7 @@ msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "pines inválidos" @@ -624,7 +624,8 @@ msgstr "len debe de ser múltiple de 4" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "la asignación de memoria ha fallado, asignando %u bytes para código nativo" +msgstr "" +"la asignación de memoria ha fallado, asignando %u bytes para código nativo" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" @@ -710,15 +711,15 @@ msgstr "parámetro config desconocido" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -737,11 +738,11 @@ msgstr "index dupterm inválido" msgid "Odd parity is not supported" msgstr "bytes > 8 bits no son soportados" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not available" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index e77e31068..783fb6771 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -373,7 +373,7 @@ msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Mali ang pins" @@ -709,17 +709,17 @@ msgstr "hindi alam na config param" msgid "AnalogOut functionality not supported" msgstr "Hindi supportado ang AnalogOut" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -738,11 +738,11 @@ msgstr "mali ang buffer length" msgid "Odd parity is not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 #, fuzzy msgid "busio.UART not available" msgstr "hindi pa implemented ang busio.UART" diff --git a/locale/fr.po b/locale/fr.po index bbabd8537..3af5066e6 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 11:28+0700\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -368,7 +368,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Broche invalide" @@ -705,17 +705,17 @@ msgstr "paramètre de config. inconnu" msgid "AnalogOut functionality not supported" msgstr "AnalogOut non supporté" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" @@ -734,11 +734,11 @@ msgstr "longueur de tampon invalide" msgid "Odd parity is not supported" msgstr "octets > 8 bits non supporté" -#: ports/nrf/common-hal/busio/UART.c:318 ports/nrf/common-hal/busio/UART.c:322 -#: ports/nrf/common-hal/busio/UART.c:327 ports/nrf/common-hal/busio/UART.c:332 -#: ports/nrf/common-hal/busio/UART.c:338 ports/nrf/common-hal/busio/UART.c:343 -#: ports/nrf/common-hal/busio/UART.c:348 ports/nrf/common-hal/busio/UART.c:352 -#: ports/nrf/common-hal/busio/UART.c:360 +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 #, fuzzy msgid "busio.UART not available" msgstr "busio.UART pas encore implémenté" @@ -2425,10 +2425,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" - #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 723c9bc8e..d6b283c9f 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-02 01:19-0300\n" +"POT-Creation-Date: 2018-10-03 23:15+0700\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -361,7 +361,7 @@ msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:77 +#: ports/nrf/common-hal/busio/I2C.c:81 msgid "Invalid pins" msgstr "Pinos inválidos" @@ -378,10 +378,12 @@ msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" #: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" msgstr "Falha ao alocar buffer RX" @@ -390,10 +392,12 @@ msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" #: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 msgid "No RX pin" msgstr "Nenhum pino RX" #: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 msgid "No TX pin" msgstr "Nenhum pino TX" @@ -690,24 +694,39 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:91 +#: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:109 +#: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:170 +#: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 -#: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 -#: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 -#: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 -#: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 -msgid "busio.UART not yet implemented" +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "Arquivo inválido" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "I2C operação não suportada" + +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" msgstr "" #: ports/nrf/common-hal/microcontroller/Processor.c:49 @@ -2254,7 +2273,8 @@ msgstr "Limite deve estar no alcance de 0-65536" #: shared-bindings/util.c:38 msgid "" "Object has been deinitialized and can no longer be used. Create a new object." -msgstr "Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." +msgstr "" +"Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" -- cgit v1.2.3 From 38d99b11c180c877fc4060d8383b0a949a94dc42 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:13:01 +1000 Subject: Copy wiznet drivers over from MicroPython 1.9.4 --- drivers/wiznet5k/README.md | 6 + drivers/wiznet5k/ethernet/socket.c | 724 +++++++++++ drivers/wiznet5k/ethernet/socket.h | 472 +++++++ drivers/wiznet5k/ethernet/w5200/w5200.c | 206 +++ drivers/wiznet5k/ethernet/w5200/w5200.h | 2092 ++++++++++++++++++++++++++++++ drivers/wiznet5k/ethernet/w5500/w5500.c | 247 ++++ drivers/wiznet5k/ethernet/w5500/w5500.h | 2057 +++++++++++++++++++++++++++++ drivers/wiznet5k/ethernet/wizchip_conf.c | 662 ++++++++++ drivers/wiznet5k/ethernet/wizchip_conf.h | 554 ++++++++ drivers/wiznet5k/internet/dhcp/dhcp.c | 978 ++++++++++++++ drivers/wiznet5k/internet/dhcp/dhcp.h | 150 +++ drivers/wiznet5k/internet/dns/dns.c | 566 ++++++++ drivers/wiznet5k/internet/dns/dns.h | 96 ++ 13 files changed, 8810 insertions(+) create mode 100644 drivers/wiznet5k/README.md create mode 100644 drivers/wiznet5k/ethernet/socket.c create mode 100644 drivers/wiznet5k/ethernet/socket.h create mode 100644 drivers/wiznet5k/ethernet/w5200/w5200.c create mode 100644 drivers/wiznet5k/ethernet/w5200/w5200.h create mode 100644 drivers/wiznet5k/ethernet/w5500/w5500.c create mode 100644 drivers/wiznet5k/ethernet/w5500/w5500.h create mode 100644 drivers/wiznet5k/ethernet/wizchip_conf.c create mode 100644 drivers/wiznet5k/ethernet/wizchip_conf.h create mode 100644 drivers/wiznet5k/internet/dhcp/dhcp.c create mode 100644 drivers/wiznet5k/internet/dhcp/dhcp.h create mode 100644 drivers/wiznet5k/internet/dns/dns.c create mode 100644 drivers/wiznet5k/internet/dns/dns.h diff --git a/drivers/wiznet5k/README.md b/drivers/wiznet5k/README.md new file mode 100644 index 000000000..88f25a2b8 --- /dev/null +++ b/drivers/wiznet5k/README.md @@ -0,0 +1,6 @@ +This is the driver for the WIZnet5x00 series of Ethernet controllers. + +Adapted for MicroPython. + +Original source: https://github.com/Wiznet/W5500_EVB/tree/master/ioLibrary +Taken on: 30 August 2014 diff --git a/drivers/wiznet5k/ethernet/socket.c b/drivers/wiznet5k/ethernet/socket.c new file mode 100644 index 000000000..ec25fcc79 --- /dev/null +++ b/drivers/wiznet5k/ethernet/socket.c @@ -0,0 +1,724 @@ +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. +//! Copy 4 byte addr value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include + +#include "py/mpthread.h" +#include "socket.h" + +#define SOCK_ANY_PORT_NUM 0xC000; + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; +static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; + +#if _WIZCHIP_ == 5200 + static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; +#endif + +#define CHECK_SOCKNUM() \ + do{ \ + if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + }while(0); \ + +#define CHECK_SOCKMODE(mode) \ + do{ \ + if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + }while(0); \ + +#define CHECK_SOCKINIT() \ + do{ \ + if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + }while(0); \ + +#define CHECK_SOCKDATA() \ + do{ \ + if(len == 0) return SOCKERR_DATALEN; \ + }while(0); \ + +void WIZCHIP_EXPORT(socket_reset)(void) { + sock_any_port = SOCK_ANY_PORT_NUM; + sock_io_mode = 0; + sock_is_sending = 0; + /* + memset(sock_remained_size, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t)); + memset(sock_pack_info, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint8_t)); + */ + +#if _WIZCHIP_ == 5200 + memset(sock_next_rd, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t)); +#endif +} + +int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) +{ + CHECK_SOCKNUM(); + switch(protocol) + { + case Sn_MR_TCP : + case Sn_MR_UDP : + case Sn_MR_MACRAW : + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW : + case Sn_MR_PPPoE : + break; + #endif + default : + return SOCKERR_SOCKMODE; + } + if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if(flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if(flag != 0) + { + switch(protocol) + { + case Sn_MR_TCP: + if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; + break; + case Sn_MR_UDP: + if(flag & SF_IGMP_VER2) + { + if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; + } + #if _WIZCHIP_ == 5500 + if(flag & SF_UNI_BLOCK) + { + if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } + #endif + break; + default: + break; + } + } + WIZCHIP_EXPORT(close)(sn); + setSn_MR(sn, (protocol | (flag & 0xF0))); + if(!port) + { + port = sock_any_port++; + if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn,port); + setSn_CR(sn,Sn_CR_OPEN); + while(getSn_CR(sn)); + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1< freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) + { + WIZCHIP_EXPORT(close)(sn); + return SOCKERR_SOCKSTATUS; + } + if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + MICROPY_THREAD_YIELD(); + } + wiz_send_data(sn, buf, len); + #if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; + #endif + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending |= (1 << sn); + return len; +} + + +int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp = 0; + uint16_t recvsize = 0; + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if(recvsize < len) len = recvsize; + while(1) + { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) + { + if(tmp == SOCK_CLOSE_WAIT) + { + if(recvsize != 0) break; + else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) + { + // dpgeorge: Getting here seems to be an orderly shutdown of the + // socket, and trying to get POSIX behaviour we return 0 because: + // "If no messages are available to be received and the peer has per‐ + // formed an orderly shutdown, recv() shall return 0". + // TODO this return value clashes with SOCK_BUSY in non-blocking mode. + WIZCHIP_EXPORT(close)(sn); + return 0; + } + } + else + { + WIZCHIP_EXPORT(close)(sn); + return SOCKERR_SOCKSTATUS; + } + } + if((sock_io_mode & (1< freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + MICROPY_THREAD_YIELD(); + }; + wiz_send_data(sn, buf, len); + + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR(wizchip_getsubn()); + #endif + + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + while(1) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + //M:20131104 + //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if(tmp & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + return SOCKERR_TIMEOUT; + } + //////////// + MICROPY_THREAD_YIELD(); + } + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + return len; +} + + + +int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) +{ + uint8_t mr; + uint8_t head[8]; + uint16_t pack_len=0; + + CHECK_SOCKNUM(); + //CHECK_SOCKMODE(Sn_MR_UDP); + switch((mr=getSn_MR(sn)) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + case Sn_MR_PPPoE: + break; + #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if(sock_remained_size[sn] == 0) + { + while(1) + { + pack_len = getSn_RX_RSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1< 1514) + { + WIZCHIP_EXPORT(close)(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn,buf,pack_len); + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 6); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + #endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn,Sn_CR_RECV); + /* wait to process the command... */ + while(getSn_CR(sn)) ; + sock_remained_size[sn] -= pack_len; + //M20140501 : replace 0x01 with PACK_REMAINED + //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; + // + return pack_len; +} + + +int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg) +{ + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch(cstype) + { + case CS_SET_IOMODE: + tmp = *((uint8_t*)arg); + if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1< explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t*)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t*)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t*)arg) = getSn_IR(sn); + break; + case CS_SET_INTMASK: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTMASK: + *((uint8_t*)arg) = getSn_IMR(sn); + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg) +{ + // M20131220 : Remove warning + //uint8_t tmp; + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_TTL: + setSn_TTL(sn,*(uint8_t*)arg); + break; + case SO_TOS: + setSn_TOS(sn,*(uint8_t*)arg); + break; + case SO_MSS: + setSn_MSSR(sn,*(uint16_t*)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t*)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); + #if _WIZCHIP_ > 5200 + if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; + #endif + setSn_CR(sn,Sn_CR_SEND_KEEP); + while(getSn_CR(sn) != 0) + { + // M20131220 + //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn,*(uint8_t*)arg); + break; + #endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg) +{ + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_FLAG: + *(uint8_t*)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t*) arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t*) arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint8_t*) arg = getSn_MSSR(sn); + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + *(uint16_t*) arg = getSn_DPORT(sn); + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t*) arg = getSn_KPALVTR(sn); + break; + #endif + case SO_SENDBUF: + *(uint16_t*) arg = getSn_TX_FSR(sn); + case SO_RECVBUF: + *(uint16_t*) arg = getSn_RX_RSR(sn); + case SO_STATUS: + *(uint8_t*) arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if(getSn_MR(sn) == Sn_MR_TCP) + *(uint16_t*)arg = getSn_RX_RSR(sn); + else + *(uint16_t*)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint8_t*)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} diff --git a/drivers/wiznet5k/ethernet/socket.h b/drivers/wiznet5k/ethernet/socket.h new file mode 100644 index 000000000..2f03a34eb --- /dev/null +++ b/drivers/wiznet5k/ethernet/socket.h @@ -0,0 +1,472 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. + * But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, + * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n + * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. + * When the listen SOCKET accepts a connection request from a client, it keeps listening. + * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n + * Following figure shows network flow diagram by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n + * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, + * it is changed in order to communicate with the client. + * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n + * If there're many listen SOCKET with same listen port number and a client requests a connection, + * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _WIZCHIP_SOCKET_H_ +#define _WIZCHIP_SOCKET_H_ + +// use this macro for exported names to avoid name clashes +#define WIZCHIP_EXPORT(name) wizchip_ ## name + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 + #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 + #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 + #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 + #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 +#endif + +#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. +#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. +#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + +// resets all global state associated with the socket interface +void WIZCHIP_EXPORT(socket_reset)(void); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n + * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t WIZCHIP_EXPORT(close)(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t WIZCHIP_EXPORT(listen)(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned immediately\n + */ +int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n + * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n + * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n + * In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer. \n + * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n + * Even if the connectionless socket has been previously connected to a specific address, + * the address and port number parameters override the destination address for that particular datagram only. + * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than len. + * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n + * This function is used to receive UDP and MAC_RAW mode, and handle the header as well. + * This function can divide to received the packet data. + * On the MACRAW SOCKET, the addr and port parameters are ignored. + * @note In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer + * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet sized. + * When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * It is valid only when the first call recvfrom for receiving the packet. + * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the packet. +* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); + + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum +{ + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + SIK_ALL = 0x1F, ///< all interrupt +}sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum +{ + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind +}ctlsock_type; + + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum +{ + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to flag in @ref socket(). + SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set/Get the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode + #if _WIZCHIP_ > 5200 + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode + #endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. +}sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. + * Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. \n + * + * + * + * + * + *
@b cstype @b data type@b value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
@ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + * + * + * + * + *
@b sotype @b data type@b value
@ref SO_TTL uint8_t 0 ~ 255
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ 65535
@ref SO_KEEPALIVESEND null null
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n + */ +int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + * + * + * + * + * + * + * + * + *
@b sotype @b data type@b value
@ref SO_FLAG uint8_t @ref SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
@ref SO_SENDBUF uint16_t 0 ~ 65535
@ref SO_RECVBUF uint16_t 0 ~ 65535
@ref SO_STATUS uint8_t @ref SOCK_ESTABLISHED, etc..
@ref SO_REMAINSIZE uint16_t 0~ 65535
@ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc...
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n + * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, + * This means the zero byte UDP data(UDP Header only) received. + */ +int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg); + +#endif // _WIZCHIP_SOCKET_H_ diff --git a/drivers/wiznet5k/ethernet/w5200/w5200.c b/drivers/wiznet5k/ethernet/w5200/w5200.c new file mode 100644 index 000000000..8c3780792 --- /dev/null +++ b/drivers/wiznet5k/ethernet/w5200/w5200.c @@ -0,0 +1,206 @@ +// dpgeorge: this file taken from w5500/w5500.c and adapted to W5200 + +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "w5200.h" + +#define SMASK (0x7ff) /* tx buffer mask */ +#define RMASK (0x7ff) /* rx buffer mask */ +#define SSIZE (2048) /* max tx buffer size */ +#define RSIZE (2048) /* max rx buffer size */ + +#define TXBUF_BASE (0x8000) +#define RXBUF_BASE (0xc000) +#define SBASE(sn) (TXBUF_BASE + SSIZE * (sn)) /* tx buffer base for socket sn */ +#define RBASE(sn) (RXBUF_BASE + RSIZE * (sn)) /* rx buffer base for socket sn */ + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + uint8_t spi_data[4] = { + AddrSel >> 8, + AddrSel, + 0x00, + 0x01, + }; + WIZCHIP.IF.SPI._write_bytes(spi_data, 4); + uint8_t ret; + WIZCHIP.IF.SPI._read_bytes(&ret, 1); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + uint8_t spi_data[5] = { + AddrSel >> 8, + AddrSel, + 0x80, + 0x01, + wb, + }; + WIZCHIP.IF.SPI._write_bytes(spi_data, 5); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) { + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + uint8_t spi_data[4] = { + AddrSel >> 8, + AddrSel, + 0x00 | ((len >> 8) & 0x7f), + len & 0xff, + }; + WIZCHIP.IF.SPI._write_bytes(spi_data, 4); + WIZCHIP.IF.SPI._read_bytes(pBuf, len); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) { + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + uint8_t spi_data[4] = { + AddrSel >> 8, + AddrSel, + 0x80 | ((len >> 8) & 0x7f), + len & 0xff, + }; + WIZCHIP.IF.SPI._write_bytes(spi_data, 4); + WIZCHIP.IF.SPI._write_bytes(pBuf, len); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + do { + val1 = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1); + if (val1 != 0) { + val = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + do { + val1 = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1); + if (val1 != 0) { + val = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + if (len == 0) { + return; + } + + uint16_t ptr = getSn_TX_WR(sn); + uint16_t offset = ptr & SMASK; + uint32_t addr = offset + SBASE(sn); + + if (offset + len > SSIZE) { + // implement wrap-around circular buffer + uint16_t size = SSIZE - offset; + WIZCHIP_WRITE_BUF(addr, wizdata, size); + WIZCHIP_WRITE_BUF(SBASE(sn), wizdata + size, len - size); + } else { + WIZCHIP_WRITE_BUF(addr, wizdata, len); + } + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + if (len == 0) { + return; + } + + uint16_t ptr = getSn_RX_RD(sn); + uint16_t offset = ptr & RMASK; + uint16_t addr = RBASE(sn) + offset; + + if (offset + len > RSIZE) { + // implement wrap-around circular buffer + uint16_t size = RSIZE - offset; + WIZCHIP_READ_BUF(addr, wizdata, size); + WIZCHIP_READ_BUF(RBASE(sn), wizdata + size, len - size); + } else { + WIZCHIP_READ_BUF(addr, wizdata, len); + } + + ptr += len; + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} diff --git a/drivers/wiznet5k/ethernet/w5200/w5200.h b/drivers/wiznet5k/ethernet/w5200/w5200.h new file mode 100644 index 000000000..63561940f --- /dev/null +++ b/drivers/wiznet5k/ethernet/w5200/w5200.h @@ -0,0 +1,2092 @@ +// dpgeorge: this file taken from w5500/w5500.h and adapted to W5200 + +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5200_H_ +#define _W5200_H_ + +#include +#include "../wizchip_conf.h" +//#include "board.h" + +#define _W5200_IO_BASE_ 0x00000000 + +#define WIZCHIP_CREG_ADDR(addr) (_W5200_IO_BASE_ + (addr)) + +#define WIZCHIP_CH_BASE (0x4000) +#define WIZCHIP_CH_SIZE (0x100) +#define WIZCHIP_SREG_ADDR(sn, addr) (_W5200_IO_BASE_ + WIZCHIP_CH_BASE + (sn) * WIZCHIP_CH_SIZE + (addr)) + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function + */ + + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa RTR, RCR : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + + + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + + + /** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end -------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + *
7 6 5 4 3 2 1 0
RST Reserved WOL PB PPPoE Reserved FARP Reserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR WIZCHIP_CREG_ADDR(0x0000) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR WIZCHIP_CREG_ADDR(0x0001) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR WIZCHIP_CREG_ADDR(0x0005) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR WIZCHIP_CREG_ADDR(0x0009) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR WIZCHIP_CREG_ADDR(0x000f) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +//#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. + * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of @ref IR defined as follows. + * + * + * + *
7 6 5 4 3 2 1 0
CONFLICT UNREACH PPPoE MP Reserved Reserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR WIZCHIP_CREG_ADDR(0x0015) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. + * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n + * Each bit of @ref IMR defined as the following. + * + * + * + *
7 6 5 4 3 2 1 0
IM_IR7 IM_IR6 IM_IR5 IM_IR4 Reserved Reserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +#define IMR WIZCHIP_CREG_ADDR(0x0016) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ +//#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. + * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is + */ +//#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. + */ +#define RTR WIZCHIP_CREG_ADDR(0x0017) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref RCR configures the number of time of retransmission. + * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . + */ +#define RCR WIZCHIP_CREG_ADDR(0x0019) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER WIZCHIP_CREG_ADDR(0x0028) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC WIZCHIP_CREG_ADDR(0x0029) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. + */ +//#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. + */ +//#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +//#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates + * the destination IP address & port number respectively. + */ +//#define UIPR (_W5500_IO_BASE_ + (0x002a << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR + * indicates the destination IP address & port number respectively. + */ +//#define UPORTR (_W5500_IO_BASE_ + (0x002e << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. + */ +//#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) +#define PHYSTATUS WIZCHIP_CREG_ADDR(0x0035) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +//#define VERSIONR (_W5200_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + + +//----------------------------- W5500 Socket Registers IOMAP ----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + *
7 6 5 4 3 2 1 0
MULTI/MFEN BCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3] Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + *
Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0 MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) WIZCHIP_SREG_ADDR(N, 0x0000) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) WIZCHIP_SREG_ADDR(N, 0x0001) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
7 6 5 4 3 2 1 0
Reserved Reserved Reserved SEND_OK TIMEOUT RECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) WIZCHIP_SREG_ADDR(N, 0x0002) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) WIZCHIP_SREG_ADDR(N, 0x0003) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORT(N) WIZCHIP_SREG_ADDR(N, 0x0004) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) WIZCHIP_SREG_ADDR(N, 0x0006) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of �TCP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of �TCP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) WIZCHIP_SREG_ADDR(N, 0x000c) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In �TCP clientmode, it configures the listen port number of �TCP serverbefore CONNECT command. + * In �TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) WIZCHIP_SREG_ADDR(N, 0x0010) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(N) WIZCHIP_SREG_ADDR(N, 0x0012) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(N) WIZCHIP_SREG_ADDR(N, 0x0015) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(N) WIZCHIP_SREG_ADDR(N, 0x0016) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) WIZCHIP_SREG_ADDR(N, 0x001e) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) WIZCHIP_SREG_ADDR(N, 0x001f) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. + * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) WIZCHIP_SREG_ADDR(N, 0x0020) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(N) WIZCHIP_SREG_ADDR(N, 0x0022) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) WIZCHIP_SREG_ADDR(N, 0x0024) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between + * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) WIZCHIP_SREG_ADDR(N, 0x0026) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) WIZCHIP_SREG_ADDR(N, 0x0028) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(N) WIZCHIP_SREG_ADDR(N, 0x002a) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +//#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +//#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +//#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + + +//----------------------------- W5500 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. + */ +#define IR_MP 0x10 + + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7<<3) +#define PHYCFGR_OPMDC_PDOWN (6<<3) +#define PHYCFGR_OPMDC_NA (5<<3) +#define PHYCFGR_OPMDC_100FA (4<<3) +#define PHYCFGR_OPMDC_100F (3<<3) +#define PHYCFGR_OPMDC_100H (2<<3) +#define PHYCFGR_OPMDC_10F (1<<3) +#define PHYCFGR_OPMDC_10H (0<<3) +#define PHYCFGR_DPX_FULL (1<<2) +#define PHYCFGR_DPX_HALF (0<<2) +#define PHYCFGR_SPD_100 (1<<1) +#define PHYCFGR_SPD_10 (0<<1) +#define PHYCFGR_LNK_ON (1<<0) +#define PHYCFGR_LNK_OFF (0<<0) + +// PHYSTATUS register +#define PHYSTATUS_POWERDOWN (0x08) +#define PHYSTATUS_LINK (0x20) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m + * In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +//#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = + */ +//#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5500 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * + * + * + * + * + * + *
\b Sn_MR (P[3:0]) \b Sn_SR
Sn_MR_CLOSE (000
Sn_MR_TCP (001 SOCK_INIT (0x13)
Sn_MR_UDP (010 SOCK_UDP (0x22)
S0_MR_MACRAW (100 SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). + * In this mode, Socket n operates as a �TCP serverand waits for connection-request (SYN packet) from any �TCP client + * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. + * When a �TCP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a �TCP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to b>TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of b>TCP serveror b>TCP client the DISCON command processes the disconnect-process (b>Active closeor b>Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\N + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\N + * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N + * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as b>TCP servermode and waiting for connection-request (SYN packet) from a peer (b>TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVERprocessed the SYN packet from the b>TCP CLIENTduring @ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n + * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#ifdef _exit +#undef _exit +#endif +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) \ + WIZCHIP_WRITE(MR,mr) + + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() \ + WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +// dpgeorge: not yet implemented +#define setINTLEVEL(intlevel) (void)intlevel +#if 0 +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } +#endif + + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// dpgeorge: not yet implemented +#define getINTLEVEL() (0) +#if 0 +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref IMR register + * @param (uint8_t)imr Value to set @ref IMR register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(IMR, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IMR register + * @return uint8_t. Value of @ref IMR register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(IMR) + + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +// dpgeorge: not yet implemented +#define setSIR(sir) ((void)sir) +#if 0 +#define setSIR(sir) \ + WIZCHIP_WRITE(SIR, sir) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +// dpgeorge: not yet implemented +#define getSIR() (0) +#if 0 +#define getSIR() \ + WIZCHIP_READ(SIR) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +// dpgeorge: not yet implemented +#define setSIMR(simr) ((void)simr) +#if 0 +#define setSIMR(simr) \ + WIZCHIP_WRITE(SIMR, simr) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +// dpgeorge: not yet implemented +#define getSIMR() (0) +#if 0 +#define getSIMR() \ + WIZCHIP_READ(SIMR) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RTR register + * @param (uint16_t)rtr Value to set @ref RTR register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(RTR + 1, (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RTR register + * @return uint16_t. Value of @ref RTR register. + * @sa setRTR() + */ +#define getRTR() \ + ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(RTR + 1)) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RCR register + * @param (uint8_t)rcr Value to set @ref RCR register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(RCR, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RCR register + * @return uint8_t. Value of @ref RCR register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(RCR) + +//================================================== test done =========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#if 0 +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) {\ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +//uint16_t getPSID(void); +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) \ + WIZCHIP_WRITE(PHYCFGR, phycfgr) +#endif + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYSTATUS() \ + WIZCHIP_READ(PHYSTATUS) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +/* +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + */ +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +// dpgeorge: not yet implemented +#define setSn_IMR(sn, imr) (void)sn; (void)imr +#if 0 +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) +#endif + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +// dpgeorge: not yet implemented +#define getSn_IMR(sn) (0) +#if 0 +#define getSn_IMR(sn) \ + (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) +#endif + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(Sn_PORT(sn) + 1, (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) | WIZCHIP_READ(Sn_PORT(sn) + 1)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(Sn_DPORT(sn) + 1, (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ((Sn_DPORT(sn)+1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE((Sn_MSSR(sn)+1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ((Sn_MSSR(sn)+1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ((Sn_TX_RD(sn)+1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE((Sn_TX_WR(sn)+1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ((Sn_TX_WR(sn)+1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE((Sn_RX_RD(sn)+1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ((Sn_RX_RD(sn)+1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ((Sn_RX_WR(sn)+1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#if 0 // dpgeorge +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// +#endif + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) + +/** + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +//uint16_t getSn_TxMAX(uint8_t sn); +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) + +void wiz_init(void); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +#endif // _W5500_H_ diff --git a/drivers/wiznet5k/ethernet/w5500/w5500.c b/drivers/wiznet5k/ethernet/w5500/w5500.c new file mode 100644 index 000000000..3107b1b71 --- /dev/null +++ b/drivers/wiznet5k/ethernet/w5500/w5500.c @@ -0,0 +1,247 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +//////////////////////////////////////////////////// + +#define LPC_SSP0 (0) + +static void Chip_SSP_ReadFrames_Blocking(int dummy, uint8_t *buf, uint32_t len) { + WIZCHIP.IF.SPI._read_bytes(buf, len); +} + +static void Chip_SSP_WriteFrames_Blocking(int dummy, const uint8_t *buf, uint32_t len) { + WIZCHIP.IF.SPI._write_bytes(buf, len); +} + +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + //ret = WIZCHIP.IF.SPI._read_byte(); + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); + Chip_SSP_ReadFrames_Blocking(LPC_SSP0, &ret, 1); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + //WIZCHIP.IF.SPI._write_byte(wb); + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 4); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + //uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + //for(i = 0; i < len; i++) + // pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); + Chip_SSP_ReadFrames_Blocking(LPC_SSP0, pBuf, len); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + //uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + //for(i = 0; i < len; i++) + // WIZCHIP.IF.SPI._write_byte(pBuf[i]); + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3); + Chip_SSP_WriteFrames_Blocking(LPC_SSP0, pBuf, len); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_TX_WR(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel,wizdata, len); + + ptr += len; + setSn_TX_WR(sn,ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_RX_RD(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn,ptr); +} + + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn,ptr); +} + diff --git a/drivers/wiznet5k/ethernet/w5500/w5500.h b/drivers/wiznet5k/ethernet/w5500/w5500.h new file mode 100644 index 000000000..c2afb180e --- /dev/null +++ b/drivers/wiznet5k/ethernet/w5500/w5500.h @@ -0,0 +1,2057 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5500_H_ +#define _W5500_H_ + +#include +#include "../wizchip_conf.h" + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address + + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function + */ + + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa RTR, RCR : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + + + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + + + /** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end -------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + *
7 6 5 4 3 2 1 0
RST Reserved WOL PB PPPoE Reserved FARP Reserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. + * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of @ref IR defined as follows. + * + * + * + *
7 6 5 4 3 2 1 0
CONFLICT UNREACH PPPoE MP Reserved Reserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. + * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n + * Each bit of @ref IMR defined as the following. + * + * + * + *
7 6 5 4 3 2 1 0
IM_IR7 IM_IR6 IM_IR5 IM_IR4 Reserved Reserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. + * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. + */ +#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref RCR configures the number of time of retransmission. + * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . + */ +#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates + * the destination IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR + * indicates the destination IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + + +//----------------------------- W5500 Socket Registers IOMAP ----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + *
7 6 5 4 3 2 1 0
MULTI/MFEN BCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3] Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + *
Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0 MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
7 6 5 4 3 2 1 0
Reserved Reserved Reserved SEND_OK TIMEOUT RECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of �TCP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of �TCP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In �TCP clientmode, it configures the listen port number of �TCP serverbefore CONNECT command. + * In �TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. + * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between + * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + + +//----------------------------- W5500 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. + */ +#define IR_MP 0x10 + + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7<<3) +#define PHYCFGR_OPMDC_PDOWN (6<<3) +#define PHYCFGR_OPMDC_NA (5<<3) +#define PHYCFGR_OPMDC_100FA (4<<3) +#define PHYCFGR_OPMDC_100F (3<<3) +#define PHYCFGR_OPMDC_100H (2<<3) +#define PHYCFGR_OPMDC_10F (1<<3) +#define PHYCFGR_OPMDC_10H (0<<3) +#define PHYCFGR_DPX_FULL (1<<2) +#define PHYCFGR_DPX_HALF (0<<2) +#define PHYCFGR_SPD_100 (1<<1) +#define PHYCFGR_SPD_10 (0<<1) +#define PHYCFGR_LNK_ON (1<<0) +#define PHYCFGR_LNK_OFF (0<<0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m + * In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5500 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * + * + * + * + * + * + *
\b Sn_MR (P[3:0]) \b Sn_SR
Sn_MR_CLOSE (000
Sn_MR_TCP (001 SOCK_INIT (0x13)
Sn_MR_UDP (010 SOCK_UDP (0x22)
S0_MR_MACRAW (100 SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). + * In this mode, Socket n operates as a �TCP serverand waits for connection-request (SYN packet) from any �TCP client + * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. + * When a �TCP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a �TCP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to b>TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of b>TCP serveror b>TCP client the DISCON command processes the disconnect-process (b>Active closeor b>Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\N + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\N + * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N + * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as b>TCP servermode and waiting for connection-request (SYN packet) from a peer (b>TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVERprocessed the SYN packet from the b>TCP CLIENTduring @ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n + * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#ifdef _exit +#undef _exit +#endif +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) \ + WIZCHIP_WRITE(MR,mr) + + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() \ + WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } + + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref IMR register + * @param (uint8_t)imr Value to set @ref IMR register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(IMR, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IMR register + * @return uint8_t. Value of @ref IMR register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(IMR) + + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) \ + WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() \ + WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) \ + WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() \ + WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RTR register + * @param (uint16_t)rtr Value to set @ref RTR register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RTR register + * @return uint16_t. Value of @ref RTR register. + * @sa setRTR() + */ +#define getRTR() \ + ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(RTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RCR register + * @param (uint8_t)rcr Value to set @ref RCR register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(RCR, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RCR register + * @return uint8_t. Value of @ref RCR register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(RCR) + +//================================================== test done =========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) {\ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +//uint16_t getPSID(void); +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) \ + WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() \ + WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) + +/** + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +//uint16_t getSn_TxMAX(uint8_t sn); +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +#endif // _W5500_H_ diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.c b/drivers/wiznet5k/ethernet/wizchip_conf.c new file mode 100644 index 000000000..3e54d2c90 --- /dev/null +++ b/drivers/wiznet5k/ethernet/wizchip_conf.c @@ -0,0 +1,662 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* +//! For remove the warning when pointer type size is not 32bit. +//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +//A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" +#include "socket.h" + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_enter(void) {}; +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_exit(void) {}; +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_select(void) {}; +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_deselect(void) {}; +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + //M20140501 : Explict pointer type casting +//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); }; +uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }; +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + +//M20140501 : Explict pointer type casting +//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; }; +void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }; + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_spi_readbytes(uint8_t *buf, uint32_t len) {} +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_spi_writebytes(const uint8_t *buf, uint32_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; + +#if _WIZCHIP_ == 5200 // for W5200 ARP errata +static uint8_t _SUBN_[4]; // subnet +#endif +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) +{ + if(!cris_en || !cris_ex) + { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } + else + { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) +{ + if(!cs_sel || !cs_desel) + { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } + else + { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); + + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if(!spi_rb || !spi_wb) + { + WIZCHIP.IF.SPI._read_bytes = wizchip_spi_readbytes; + WIZCHIP.IF.SPI._write_bytes = wizchip_spi_writebytes; + } + else + { + WIZCHIP.IF.SPI._read_bytes = spi_rb; + WIZCHIP.IF.SPI._write_bytes = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) +{ + uint8_t tmp = 0; + uint8_t* ptmp[2] = {0,0}; + switch(cwtype) + { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if(arg != 0) + { + ptmp[0] = (uint8_t*)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind*)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind*)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind*)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind*)arg) = wizchip_getinterruptmask(); + break; + #if _WIZCHIP_ > 5100 + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTLEVEL(); + break; + #endif + case CW_GET_ID: + ((uint8_t*)arg)[0] = WIZCHIP.id[0]; + ((uint8_t*)arg)[1] = WIZCHIP.id[1]; + ((uint8_t*)arg)[2] = WIZCHIP.id[2]; + ((uint8_t*)arg)[3] = WIZCHIP.id[3]; + ((uint8_t*)arg)[4] = WIZCHIP.id[4]; + ((uint8_t*)arg)[5] = 0; + break; + #if _WIZCHIP_ == 5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t*)arg); + #endif + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + default: + return -1; + } + return 0; +} + + +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) +{ + + switch(cntype) + { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo*)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo*)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type*)arg); + case CN_GET_NETMODE: + *(netmode_type*)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout*)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout*)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) +{ + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; + getSHAR(mac); + getGAR(gw); getSUBR(sn); getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) +{ + int8_t i; + int8_t tmp = 0; + wizchip_sw_reset(); + if(txsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += txsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_TXBUF_SIZE(i, txsize[i]); + } + if(rxsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += rxsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_RXBUF_SIZE(i, rxsize[i]); + } + + WIZCHIP_EXPORT(socket_reset)(); + + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) +{ + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + ir |= (1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + ir |= sir; + setIR(ir); +#else + setIR(ir); + setSIR(sir); +#endif +} + +intr_kind wizchip_getinterrupt(void) +{ + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + ir = getIR(); + sir = ir 0x0F; +#else + ir = getIR(); + sir = getSIR(); +#endif + +#if _WIZCHIP_ < 5500 + ir &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) +{ + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + simr &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + imr |= simr; + setIMR(imr); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) +{ + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + imr = getIMR(); + simr = imr 0x0F; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) +{ + int8_t tmp; +#if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > 5100 + +int8_t wizphy_getphypmode(void) +{ + int8_t tmp = 0; + #if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #else + tmp = -1; + #endif + return tmp; +} +#endif + +#if _WIZCHIP_ == 5500 +void wizphy_reset(void) +{ + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + if(phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if(phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else + { + if(phyconf->duplex == PHY_DUPLEX_FULL) + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } + else + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) +{ + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if((tmp & PHYCFGR_OPMD)== 0) return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if( pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if( pmode == PHY_POWER_DOWN) + { + if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; + } + else + { + if(tmp & PHYCFGR_OPMDC_ALLA) return 0; + } + return -1; +} +#endif + + +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) +{ + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); +#if _WIZCHIP_ == 5200 // for W5200 ARP errata + _SUBN_[0] = pnetinfo->sn[0]; + _SUBN_[1] = pnetinfo->sn[1]; + _SUBN_[2] = pnetinfo->sn[2]; + _SUBN_[3] = pnetinfo->sn[3]; +#endif + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) +{ + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); +#if _WIZCHIP_ == 5200 // for W5200 ARP errata + pnetinfo->sn[0] = _SUBN_[0]; + pnetinfo->sn[1] = _SUBN_[1]; + pnetinfo->sn[2] = _SUBN_[2]; + pnetinfo->sn[3] = _SUBN_[3]; +#endif + pnetinfo->dns[0]= _DNS_[0]; + pnetinfo->dns[1]= _DNS_[1]; + pnetinfo->dns[2]= _DNS_[2]; + pnetinfo->dns[3]= _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +#if _WIZCHIP_ == 5200 // for W5200 ARP errata +uint8_t *wizchip_getsubn(void) { + return _SUBN_; +} +#endif + +int8_t wizchip_setnetmode(netmode_type netmode) +{ + uint8_t tmp = 0; +#if _WIZCHIP_ != 5500 + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; +#else + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) +{ + return (netmode_type) getMR(); +} + +void wizchip_settimeout(wiz_NetTimeout* nettime) +{ + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) +{ + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.h b/drivers/wiznet5k/ethernet/wizchip_conf.h new file mode 100644 index 000000000..4a7a7bd69 --- /dev/null +++ b/drivers/wiznet5k/ethernet/wizchip_conf.h @@ -0,0 +1,554 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n + * ex> #define \_WIZCHIP_ 5500 + */ +#ifndef _WIZCHIP_ +#define _WIZCHIP_ 5200 // 5100, 5200, 5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ + + +#if (_WIZCHIP_ == 5100) + #define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ + +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +#elif (_WIZCHIP_ == 5200) + #define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + #include "w5200/w5200.h" +#elif (_WIZCHIP_ == 5500) + #define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + */ + //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ + #include "w5500/w5500.h" +#else + #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ + #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n + * ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#define _WIZCHIP_IO_BASE_ 0x00000000 // + +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS + #ifndef _WIZCHIP_IO_BASE_ + #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." + #endif +#endif + +#if _WIZCHIP_ > 5100 + #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else + #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + + +/******************************************************** +* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. +*********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP +{ + uint16_t if_mode; ///< host interface mode + uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS + { + void (*_enter) (void); ///< crtical section enter + void (*_exit) (void); ///< critial section exit + }CRIS; + /** + * The set of @ref\_WIZCHIP_ select control callback func. + */ + struct _CS + { + void (*_select) (void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + }CS; + /** + * The set of interface IO callback func. + */ + union _IF + { + /** + * For BUS interface IO + */ + struct + { + uint8_t (*_read_byte) (uint32_t AddrSel); + void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + }BUS; + /** + * For SPI interface IO + */ + struct + { + void (*_read_bytes) (uint8_t *buf, uint32_t len); + void (*_write_bytes) (const uint8_t *buf, uint32_t len); + }SPI; + // To be added + // + }IF; +}_WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum +{ + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + +#if _WIZCHIP_ == 5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000 + CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000 +#endif + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal + CW_GET_PHYLINK ///< Get PHY Link status +}ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum +{ + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +}ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum +{ +#if _WIZCHIP_ > 5200 + IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != 5200 + IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > 5100 + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > 5100 + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt +#endif +}intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + + +#if _WIZCHIP_ == 5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, + * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n + * Valid only in W5500. + */ +typedef struct wiz_PhyConf_t +{ + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF + }wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum +{ + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +}dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t +{ + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +}wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum +{ +#if _WIZCHIP_ == 5500 + NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 +#endif + NM_WAKEONLAN = (1<<5), ///< Wake On Lan + NM_PINGBLOCK = (1<<4), ///< Block ping-request + NM_PPPOE = (1<<3), ///< PPPoE mode +}netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. + */ +typedef struct wiz_NetTimeout_t +{ + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +}wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such as + *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. + *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); + + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte usig SPI + *@param spi_wb : callback function to write byte usig SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), + * controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n + * 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); + + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +#if _WIZCHIP_ > 5100 + int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 + int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == 5500 + void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 +/** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_setphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphystat(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ + int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** +* @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +#if _WIZCHIP_ == 5200 // for W5200 ARP errata +uint8_t *wizchip_getsubn(void); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout* nettime); + +#endif // _WIZCHIP_CONF_H_ diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.c b/drivers/wiznet5k/internet/dhcp/dhcp.c new file mode 100644 index 000000000..574758259 --- /dev/null +++ b/drivers/wiznet5k/internet/dhcp/dhcp.c @@ -0,0 +1,978 @@ +//***************************************************************************** +// +//! \file dhcp.c +//! \brief DHCP APIs implement file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Optimize code +//! 2. Add reg_dhcp_cbfunc() +//! 3. Add DHCP_stop() +//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() +//! 5. Don't care system endian +//! 6. Add comments +//! <2012/12/26> V1.1.1 +//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +//#include "Ethernet/socket.h" +//#include "Internet/DHCP/dhcp.h" +#include "../../Ethernet/socket.h" +#include "dhcp.h" + +/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ + +#ifdef _DHCP_DEBUG_ + #include +#endif + +/* DHCP state machine. */ +#define STATE_DHCP_INIT 0 ///< Initialize +#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER +#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK +#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased +#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP +#define STATE_DHCP_RELEASE 5 ///< No use +#define STATE_DHCP_STOP 6 ///< Stop processing DHCP + +#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG +#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG + +/* DHCP message OP code */ +#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG +#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG + +/* DHCP message type */ +#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG +#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG +#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG +#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG +#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG +#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG +#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use +#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use + +#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG +#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG + +#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG +#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG +#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG + +#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time + +#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG +#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG + +/* + * @brief DHCP option and value (cf. RFC1533) + */ +enum +{ + padOption = 0, + subnetMask = 1, + timerOffset = 2, + routersOnSubnet = 3, + timeServer = 4, + nameServer = 5, + dns = 6, + logServer = 7, + cookieServer = 8, + lprServer = 9, + impressServer = 10, + resourceLocationServer = 11, + hostName = 12, + bootFileSize = 13, + meritDumpFile = 14, + domainName = 15, + swapServer = 16, + rootPath = 17, + extentionsPath = 18, + IPforwarding = 19, + nonLocalSourceRouting = 20, + policyFilter = 21, + maxDgramReasmSize = 22, + defaultIPTTL = 23, + pathMTUagingTimeout = 24, + pathMTUplateauTable = 25, + ifMTU = 26, + allSubnetsLocal = 27, + broadcastAddr = 28, + performMaskDiscovery = 29, + maskSupplier = 30, + performRouterDiscovery = 31, + routerSolicitationAddr = 32, + staticRoute = 33, + trailerEncapsulation = 34, + arpCacheTimeout = 35, + ethernetEncapsulation = 36, + tcpDefaultTTL = 37, + tcpKeepaliveInterval = 38, + tcpKeepaliveGarbage = 39, + nisDomainName = 40, + nisServers = 41, + ntpServers = 42, + vendorSpecificInfo = 43, + netBIOSnameServer = 44, + netBIOSdgramDistServer = 45, + netBIOSnodeType = 46, + netBIOSscope = 47, + xFontServer = 48, + xDisplayManager = 49, + dhcpRequestedIPaddr = 50, + dhcpIPaddrLeaseTime = 51, + dhcpOptionOverload = 52, + dhcpMessageType = 53, + dhcpServerIdentifier = 54, + dhcpParamRequest = 55, + dhcpMsg = 56, + dhcpMaxMsgSize = 57, + dhcpT1value = 58, + dhcpT2value = 59, + dhcpClassIdentifier = 60, + dhcpClientIdentifier = 61, + endOption = 255 +}; + +/* + * @brief DHCP message format + */ +typedef struct { + uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY + uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB + uint8_t hlen; ///< @ref DHCP_HLENETHERNET + uint8_t hops; ///< @ref DHCP_HOPS + uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. + uint16_t secs; ///< @ref DHCP_SECS + uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST + uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever + uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server + uint8_t siaddr[4]; ///< No use + uint8_t giaddr[4]; ///< No use + uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero + uint8_t sname[64]; ///< No use + uint8_t file[128]; ///< No use + uint8_t OPT[OPT_SIZE]; ///< Option +} RIP_MSG; + + + +uint8_t DHCP_SOCKET; // Socket number for DHCP + +uint8_t DHCP_SIP[4]; // DHCP Server IP address + +// Network information from DHCP Server +uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address +uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP +uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP +uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP +uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP + + +int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state +int8_t dhcp_retry_count = 0; + +uint32_t dhcp_lease_time = INFINITE_LEASETIME; +volatile uint32_t dhcp_tick_1s = 0; // unit 1 second +uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; + +uint32_t DHCP_XID; // Any number + +RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing + +uint8_t HOST_NAME[] = DCHP_HOST_NAME; + +uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. + +/* The default callback function */ +void default_ip_assign(void); +void default_ip_update(void); +void default_ip_conflict(void); + +/* Callback handler */ +void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ +void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ +void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ + +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + + +/* send DISCOVER message to DHCP server */ +void send_DHCP_DISCOVER(void); + +/* send REQEUST message to DHCP server */ +void send_DHCP_REQUEST(void); + +/* send DECLINE message to DHCP server */ +void send_DHCP_DECLINE(void); + +/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ +int8_t check_DHCP_leasedIP(void); + +/* check the timeout in DHCP process */ +uint8_t check_DHCP_timeout(void); + +/* Intialize to timeout process. */ +void reset_DHCP_timeout(void); + +/* Parse message as OFFER and ACK and NACK from DHCP server.*/ +int8_t parseDHCPCMSG(void); + +/* The default handler of ip assign first */ +void default_ip_assign(void) +{ + setSIPR(DHCP_allocated_ip); + setSUBR(DHCP_allocated_sn); + setGAR (DHCP_allocated_gw); +} + +/* The default handler of ip changed */ +void default_ip_update(void) +{ + /* WIZchip Software Reset */ + setMR(MR_RST); + getMR(); // for delay + default_ip_assign(); + setSHAR(DHCP_CHADDR); +} + +/* The default handler of ip changed */ +void default_ip_conflict(void) +{ + // WIZchip Software Reset + setMR(MR_RST); + getMR(); // for delay + setSHAR(DHCP_CHADDR); +} + +/* register the call back func. */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) +{ + dhcp_ip_assign = default_ip_assign; + dhcp_ip_update = default_ip_update; + dhcp_ip_conflict = default_ip_conflict; + if(ip_assign) dhcp_ip_assign = ip_assign; + if(ip_update) dhcp_ip_update = ip_update; + if(ip_conflict) dhcp_ip_conflict = ip_conflict; +} + +/* make the common DHCP message */ +void makeDHCPMSG(void) +{ + uint8_t bk_mac[6]; + uint8_t* ptmp; + uint8_t i; + getSHAR(bk_mac); + pDHCPMSG->op = DHCP_BOOTREQUEST; + pDHCPMSG->htype = DHCP_HTYPE10MB; + pDHCPMSG->hlen = DHCP_HLENETHERNET; + pDHCPMSG->hops = DHCP_HOPS; + ptmp = (uint8_t*)(&pDHCPMSG->xid); + *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); + *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); + *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); + *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); + pDHCPMSG->secs = DHCP_SECS; + ptmp = (uint8_t*)(&pDHCPMSG->flags); + *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); + *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); + + pDHCPMSG->ciaddr[0] = 0; + pDHCPMSG->ciaddr[1] = 0; + pDHCPMSG->ciaddr[2] = 0; + pDHCPMSG->ciaddr[3] = 0; + + pDHCPMSG->yiaddr[0] = 0; + pDHCPMSG->yiaddr[1] = 0; + pDHCPMSG->yiaddr[2] = 0; + pDHCPMSG->yiaddr[3] = 0; + + pDHCPMSG->siaddr[0] = 0; + pDHCPMSG->siaddr[1] = 0; + pDHCPMSG->siaddr[2] = 0; + pDHCPMSG->siaddr[3] = 0; + + pDHCPMSG->giaddr[0] = 0; + pDHCPMSG->giaddr[1] = 0; + pDHCPMSG->giaddr[2] = 0; + pDHCPMSG->giaddr[3] = 0; + + pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; + pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; + pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; + pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; + pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; + pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; + + for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; + for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; + for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; + + // MAGIC_COOKIE + pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); + pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); + pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); + pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; +} + +/* SEND DHCP DISCOVER */ +void send_DHCP_DISCOVER(void) +{ + uint16_t i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DISCOVER; + + // Client identifier + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x06; // length of request + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + // send broadcasting packet + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_DISCOVER\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* SEND DHCP REQUEST */ +void send_DHCP_REQUEST(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) + { + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; + pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; + pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; + pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; + ip[0] = DHCP_SIP[0]; + ip[1] = DHCP_SIP[1]; + ip[2] = DHCP_SIP[2]; + ip[3] = DHCP_SIP[3]; + } + else + { + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + } + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_REQUEST; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + { + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + } + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x08; + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = performRouterDiscovery; + pDHCPMSG->OPT[k++] = staticRoute; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_REQUEST\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + +} + +/* SEND DHCP DHCPDECLINE */ +void send_DHCP_DECLINE(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DECLINE; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + //send broadcasting packet + ip[0] = 0xFF; + ip[1] = 0xFF; + ip[2] = 0xFF; + ip[3] = 0xFF; + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Send DHCP_DECLINE\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* PARSE REPLY pDHCPMSG */ +int8_t parseDHCPMSG(void) +{ + uint8_t svr_addr[6]; + uint16_t svr_port; + uint16_t len; + + uint8_t * p; + uint8_t * e; + uint8_t type; + uint8_t opt_len; + + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) + { + len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); + #ifdef _DHCP_DEBUG_ + printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); + #endif + } + else return 0; + if (svr_port == DHCP_SERVER_PORT) { + // compare mac address + if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || + (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || + (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) + return 0; + type = 0; + p = (uint8_t *)(&pDHCPMSG->op); + p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) + e = p + (len - 240); + + while ( p < e ) { + + switch ( *p ) { + + case endOption : + p = e; // for break while(p < e) + break; + case padOption : + p++; + break; + case dhcpMessageType : + p++; + p++; + type = *p++; + break; + case subnetMask : + p++; + p++; + DHCP_allocated_sn[0] = *p++; + DHCP_allocated_sn[1] = *p++; + DHCP_allocated_sn[2] = *p++; + DHCP_allocated_sn[3] = *p++; + break; + case routersOnSubnet : + p++; + opt_len = *p++; + DHCP_allocated_gw[0] = *p++; + DHCP_allocated_gw[1] = *p++; + DHCP_allocated_gw[2] = *p++; + DHCP_allocated_gw[3] = *p++; + p = p + (opt_len - 4); + break; + case dns : + p++; + opt_len = *p++; + DHCP_allocated_dns[0] = *p++; + DHCP_allocated_dns[1] = *p++; + DHCP_allocated_dns[2] = *p++; + DHCP_allocated_dns[3] = *p++; + p = p + (opt_len - 4); + break; + case dhcpIPaddrLeaseTime : + p++; + opt_len = *p++; + dhcp_lease_time = *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + #ifdef _DHCP_DEBUG_ + dhcp_lease_time = 10; + #endif + break; + case dhcpServerIdentifier : + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + break; + default : + p++; + opt_len = *p++; + p += opt_len; + break; + } // switch + } // while + } // if + return type; +} + +uint8_t DHCP_run(void) +{ + uint8_t type; + uint8_t ret; + + if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; + + if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) + socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + + ret = DHCP_RUNNING; + type = parseDHCPMSG(); + + switch ( dhcp_state ) { + case STATE_DHCP_INIT : + DHCP_allocated_ip[0] = 0; + DHCP_allocated_ip[1] = 0; + DHCP_allocated_ip[2] = 0; + DHCP_allocated_ip[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER : + if (type == DHCP_OFFER){ +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_OFFER\r\n"); +#endif + DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; + DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; + DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; + DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_REQUEST : + if (type == DHCP_ACK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_ACK\r\n"); +#endif + if (check_DHCP_leasedIP()) { + // Network info assignment from DHCP + dhcp_ip_assign(); + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred + reset_DHCP_timeout(); + dhcp_ip_conflict(); + dhcp_state = STATE_DHCP_INIT; + } + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_LEASED : + ret = DHCP_IP_LEASED; + if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { + +#ifdef _DHCP_DEBUG_ + printf("> Maintains the IP address \r\n"); +#endif + + type = 0; + OLD_allocated_ip[0] = DHCP_allocated_ip[0]; + OLD_allocated_ip[1] = DHCP_allocated_ip[1]; + OLD_allocated_ip[2] = DHCP_allocated_ip[2]; + OLD_allocated_ip[3] = DHCP_allocated_ip[3]; + + DHCP_XID++; + + send_DHCP_REQUEST(); + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_REREQUEST; + } + break; + + case STATE_DHCP_REREQUEST : + ret = DHCP_IP_LEASED; + if (type == DHCP_ACK) { + dhcp_retry_count = 0; + if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + OLD_allocated_ip[1] != DHCP_allocated_ip[1] || + OLD_allocated_ip[2] != DHCP_allocated_ip[2] || + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) + { + ret = DHCP_IP_CHANGED; + dhcp_ip_update(); + #ifdef _DHCP_DEBUG_ + printf(">IP changed.\r\n"); + #endif + + } + #ifdef _DHCP_DEBUG_ + else printf(">IP is continued.\r\n"); + #endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + default : + break; + } + + return ret; +} + +void DHCP_stop(void) +{ + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; +} + +uint8_t check_DHCP_timeout(void) +{ + uint8_t ret = DHCP_RUNNING; + + if (dhcp_retry_count < MAX_DHCP_RETRY) { + if (dhcp_tick_next < dhcp_tick_1s) { + + switch ( dhcp_state ) { + case STATE_DHCP_DISCOVER : +// printf("<> state : STATE_DHCP_DISCOVER\r\n"); + send_DHCP_DISCOVER(); + break; + + case STATE_DHCP_REQUEST : +// printf("<> state : STATE_DHCP_REQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + case STATE_DHCP_REREQUEST : +// printf("<> state : STATE_DHCP_REREQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + default : + break; + } + + dhcp_tick_1s = 0; + dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; + dhcp_retry_count++; + } + } else { // timeout occurred + + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default : + break; + } + reset_DHCP_timeout(); + } + return ret; +} + +int8_t check_DHCP_leasedIP(void) +{ + uint8_t tmp; + int32_t ret; + + //WIZchip RCR value changed for ARP Timeout count control + tmp = getRCR(); + setRCR(0x03); + + // IP conflict detection : ARP request - ARP reply + // Broadcasting ARP Request for check the IP conflict using UDP sendto() function + ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + + // RCR value restore + setRCR(tmp); + + if(ret == SOCKERR_TIMEOUT) { + // UDP send Timeout occurred : allocated IP address is unique, DHCP Success + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Check leased IP - OK\r\n"); +#endif + + return 1; + } else { + // Received ARP reply or etc : IP address conflict occur, DHCP Failed + send_DHCP_DECLINE(); + + ret = dhcp_tick_1s; + while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; + + return 0; + } +} + +void DHCP_init(uint8_t s, uint8_t * buf) +{ + uint8_t zeroip[4] = {0,0,0,0}; + getSHAR(DHCP_CHADDR); + if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) + { + // assign temporary mac address, you should be set SHAR before call this function. + DHCP_CHADDR[0] = 0x00; + DHCP_CHADDR[1] = 0x08; + DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[3] = 0x00; + DHCP_CHADDR[4] = 0x00; + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); + } + + DHCP_SOCKET = s; // SOCK_DHCP + pDHCPMSG = (RIP_MSG*)buf; + DHCP_XID = 0x12345678; + + // WIZchip Netinfo Clear + setSIPR(zeroip); + setSIPR(zeroip); + setGAR(zeroip); + + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_INIT; +} + + +/* Rset the DHCP timeout count and retry count. */ +void reset_DHCP_timeout(void) +{ + dhcp_tick_1s = 0; + dhcp_tick_next = DHCP_WAIT_TIME; + dhcp_retry_count = 0; +} + +void DHCP_time_handler(void) +{ + dhcp_tick_1s++; +} + +void getIPfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_ip[0]; + ip[1] = DHCP_allocated_ip[1]; + ip[2] = DHCP_allocated_ip[2]; + ip[3] = DHCP_allocated_ip[3]; +} + +void getGWfromDHCP(uint8_t* ip) +{ + ip[0] =DHCP_allocated_gw[0]; + ip[1] =DHCP_allocated_gw[1]; + ip[2] =DHCP_allocated_gw[2]; + ip[3] =DHCP_allocated_gw[3]; +} + +void getSNfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_sn[0]; + ip[1] = DHCP_allocated_sn[1]; + ip[2] = DHCP_allocated_sn[2]; + ip[3] = DHCP_allocated_sn[3]; +} + +void getDNSfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_dns[0]; + ip[1] = DHCP_allocated_dns[1]; + ip[2] = DHCP_allocated_dns[2]; + ip[3] = DHCP_allocated_dns[3]; +} + +uint32_t getDHCPLeasetime(void) +{ + return dhcp_lease_time; +} + + + + diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.h b/drivers/wiznet5k/internet/dhcp/dhcp.h new file mode 100644 index 000000000..ee154d506 --- /dev/null +++ b/drivers/wiznet5k/internet/dhcp/dhcp.h @@ -0,0 +1,150 @@ +//***************************************************************************** +// +//! \file dhcp.h +//! \brief DHCP APIs Header file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Move unreferenced DEFINE to dhcp.c +//! <2012/12/26> V1.1.1 +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#ifndef _DHCP_H_ +#define _DHCP_H_ + +/* + * @brief + * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ + * @note If defined, it depends on + */ + +//#define _DHCP_DEBUG_ + +/* Retry to processing DHCP */ +#define MAX_DHCP_RETRY 2 ///< Maximum retry count +#define DHCP_WAIT_TIME 10 ///< Wait Time 10s + +/* UDP port numbers for DHCP */ +#define DHCP_SERVER_PORT 67 ///< DHCP server port number +#define DHCP_CLIENT_PORT 68 ///< DHCP client port number + +#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number + +#define DCHP_HOST_NAME "WIZnet\0" + +/* + * @brief return value of @ref DHCP_run() + */ +enum +{ + DHCP_FAILED = 0, ///< Processing Fail + DHCP_RUNNING, ///< Processing DHCP protocol + DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) + DHCP_IP_CHANGED, ///< Change IP address by new IP address from DHCP (if cbfunc == null, act as default default_ip_update) + DHCP_IP_LEASED, ///< Stand by + DHCP_STOPPED ///< Stop processing DHCP protocol +}; + +/* + * @brief DHCP client initialization (outside of the main loop) + * @param s - socket number + * @param buf - buffer for processing DHCP message + */ +void DHCP_init(uint8_t s, uint8_t * buf); + +/* + * @brief DHCP 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DHCP_time_handler(void); + +/* + * @brief Register call back function + * @param ip_assign - callback func when IP is assigned from DHCP server first + * @param ip_update - callback func when IP is changed + * @prarm ip_conflict - callback func when the assigned IP is conflict with others. + */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + +/* + * @brief DHCP client in the main loop + * @return The value is as the follow \n + * @ref DHCP_FAILED \n + * @ref DHCP_RUNNING \n + * @ref DHCP_IP_ASSIGN \n + * @ref DHCP_IP_CHANGED \n + * @ref DHCP_IP_LEASED \n + * @ref DHCP_STOPPED \n + * + * @note This function is always called by you main task. + */ +uint8_t DHCP_run(void); + +/* + * @brief Stop DHCP processing + * @note If you want to restart. call DHCP_init() and DHCP_run() + */ +void DHCP_stop(void); + +/* Get Network information assigned from DHCP server */ +/* + * @brief Get IP address + * @param ip - IP address to be returned + */ +void getIPfromDHCP(uint8_t* ip); +/* + * @brief Get Gateway address + * @param ip - Gateway address to be returned + */ +void getGWfromDHCP(uint8_t* ip); +/* + * @brief Get Subnet mask value + * @param ip - Subnet mask to be returned + */ +void getSNfromDHCP(uint8_t* ip); +/* + * @brief Get DNS address + * @param ip - DNS address to be returned + */ +void getDNSfromDHCP(uint8_t* ip); + +/* + * @brief Get the leased time by DHCP sever + * @return unit 1s + */ +uint32_t getDHCPLeasetime(void); + +#endif /* _DHCP_H_ */ diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c new file mode 100644 index 000000000..c0ad570c0 --- /dev/null +++ b/drivers/wiznet5k/internet/dns/dns.c @@ -0,0 +1,566 @@ +//***************************************************************************** +// +//! \file dns.c +//! \brief DNS APIs Implement file. +//! \details Send DNS query & Receive DNS reponse. \n +//! It depends on stdlib.h & string.h in ansi-c library +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Remove the unused define +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include +#include + +//#include "Ethernet/socket.h" +//#include "Internet/DNS/dns.h" +#include "../../ethernet/socket.h" +#include "dns.h" + +#ifdef _DNS_DEBUG_ + #include +#endif + +#define INITRTT 2000L /* Initial smoothed response time */ +#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */ + +#define TYPE_A 1 /* Host address */ +#define TYPE_NS 2 /* Name server */ +#define TYPE_MD 3 /* Mail destination (obsolete) */ +#define TYPE_MF 4 /* Mail forwarder (obsolete) */ +#define TYPE_CNAME 5 /* Canonical name */ +#define TYPE_SOA 6 /* Start of Authority */ +#define TYPE_MB 7 /* Mailbox name (experimental) */ +#define TYPE_MG 8 /* Mail group member (experimental) */ +#define TYPE_MR 9 /* Mail rename name (experimental) */ +#define TYPE_NULL 10 /* Null (experimental) */ +#define TYPE_WKS 11 /* Well-known sockets */ +#define TYPE_PTR 12 /* Pointer record */ +#define TYPE_HINFO 13 /* Host information */ +#define TYPE_MINFO 14 /* Mailbox information (experimental)*/ +#define TYPE_MX 15 /* Mail exchanger */ +#define TYPE_TXT 16 /* Text strings */ +#define TYPE_ANY 255 /* Matches any type */ + +#define CLASS_IN 1 /* The ARPA Internet */ + +/* Round trip timing parameters */ +#define AGAIN 8 /* Average RTT gain = 1/8 */ +#define LAGAIN 3 /* Log2(AGAIN) */ +#define DGAIN 4 /* Mean deviation gain = 1/4 */ +#define LDGAIN 2 /* log2(DGAIN) */ + +/* Header for all domain messages */ +struct dhdr +{ + uint16_t id; /* Identification */ + uint8_t qr; /* Query/Response */ +#define QUERY 0 +#define RESPONSE 1 + uint8_t opcode; +#define IQUERY 1 + uint8_t aa; /* Authoratative answer */ + uint8_t tc; /* Truncation */ + uint8_t rd; /* Recursion desired */ + uint8_t ra; /* Recursion available */ + uint8_t rcode; /* Response code */ +#define NO_ERROR 0 +#define FORMAT_ERROR 1 +#define SERVER_FAIL 2 +#define NAME_ERROR 3 +#define NOT_IMPL 4 +#define REFUSED 5 + uint16_t qdcount; /* Question count */ + uint16_t ancount; /* Answer count */ + uint16_t nscount; /* Authority (name server) count */ + uint16_t arcount; /* Additional record count */ +}; + + +uint8_t* pDNSMSG; // DNS message buffer +uint8_t DNS_SOCKET; // SOCKET number for DNS +uint16_t DNS_MSGID; // DNS message ID + +extern uint32_t HAL_GetTick(void); +uint32_t hal_sys_tick; + +/* converts uint16_t from network buffer to a host byte order integer. */ +uint16_t get16(uint8_t * s) +{ + uint16_t i; + i = *s++ << 8; + i = i + *s; + return i; +} + +/* copies uint16_t to the network buffer with network byte order. */ +uint8_t * put16(uint8_t * s, uint16_t i) +{ + *s++ = i >> 8; + *s++ = i; + return s; +} + + +/* + * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM + * + * Description : This function converts a compressed domain name to the human-readable form + * Arguments : msg - is a pointer to the reply message + * compressed - is a pointer to the domain name in reply message. + * buf - is a pointer to the buffer for the human-readable form name. + * len - is the MAX. size of buffer. + * Returns : the length of compressed message + */ +int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len) +{ + uint16_t slen; /* Length of current segment */ + uint8_t * cp; + int clen = 0; /* Total length of compressed name */ + int indirect = 0; /* Set if indirection encountered */ + int nseg = 0; /* Total number of segments in name */ + + cp = compressed; + + for (;;) + { + slen = *cp++; /* Length of this segment */ + + if (!indirect) clen++; + + if ((slen & 0xc0) == 0xc0) + { + if (!indirect) + clen++; + indirect = 1; + /* Follow indirection */ + cp = &msg[((slen & 0x3f)<<8) + *cp]; + slen = *cp++; + } + + if (slen == 0) /* zero length == all done */ + break; + + len -= slen + 1; + + if (len < 0) return -1; + + if (!indirect) clen += slen; + + while (slen-- != 0) *buf++ = (char)*cp++; + *buf++ = '.'; + nseg++; + } + + if (nseg == 0) + { + /* Root name; represent as single dot */ + *buf++ = '.'; + len--; + } + + *buf++ = '\0'; + len--; + + return clen; /* Length of compressed message */ +} + +/* + * PARSE QUESTION SECTION + * + * Description : This function parses the question record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the question record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_question(uint8_t * msg, uint8_t * cp) +{ + int len; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + + if (len == -1) return 0; + + cp += len; + cp += 2; /* type */ + cp += 2; /* class */ + + return cp; +} + + +/* + * PARSE ANSER SECTION + * + * Description : This function parses the answer record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the answer record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns) +{ + int len, type; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + if (len == -1) return 0; + + cp += len; + type = get16(cp); + cp += 2; /* type */ + cp += 2; /* class */ + cp += 4; /* ttl */ + cp += 2; /* len */ + + + switch (type) + { + case TYPE_A: + /* Just read the address directly into the structure */ + ip_from_dns[0] = *cp++; + ip_from_dns[1] = *cp++; + ip_from_dns[2] = *cp++; + ip_from_dns[3] = *cp++; + break; + case TYPE_CNAME: + case TYPE_MB: + case TYPE_MG: + case TYPE_MR: + case TYPE_NS: + case TYPE_PTR: + /* These types all consist of a single domain name */ + /* convert it to ASCII format */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_HINFO: + len = *cp++; + cp += len; + + len = *cp++; + cp += len; + break; + case TYPE_MX: + cp += 2; + /* Get domain name of exchanger */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_SOA: + /* Get domain name of name server */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + /* Get domain name of responsible person */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + cp += 4; + cp += 4; + cp += 4; + cp += 4; + cp += 4; + break; + case TYPE_TXT: + /* Just stash */ + break; + default: + /* Ignore */ + break; + } + + return cp; +} + +/* + * PARSE THE DNS REPLY + * + * Description : This function parses the reply message from DNS server. + * Arguments : dhdr - is a pointer to the header for DNS message + * buf - is a pointer to the reply message. + * len - is the size of reply message. + * Returns : -1 - Domain name length is too big + * 0 - Fail (Timeout or parse error) + * 1 - Success, + */ +int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns) +{ + uint16_t tmp; + uint16_t i; + uint8_t * msg; + uint8_t * cp; + + msg = pbuf; + memset(pdhdr, 0, sizeof(*pdhdr)); + + pdhdr->id = get16(&msg[0]); + tmp = get16(&msg[2]); + if (tmp & 0x8000) pdhdr->qr = 1; + + pdhdr->opcode = (tmp >> 11) & 0xf; + + if (tmp & 0x0400) pdhdr->aa = 1; + if (tmp & 0x0200) pdhdr->tc = 1; + if (tmp & 0x0100) pdhdr->rd = 1; + if (tmp & 0x0080) pdhdr->ra = 1; + + pdhdr->rcode = tmp & 0xf; + pdhdr->qdcount = get16(&msg[4]); + pdhdr->ancount = get16(&msg[6]); + pdhdr->nscount = get16(&msg[8]); + pdhdr->arcount = get16(&msg[10]); + + + /* Now parse the variable length sections */ + cp = &msg[12]; + + /* Question section */ + for (i = 0; i < pdhdr->qdcount; i++) + { + cp = dns_question(msg, cp); + if(!cp) + { +#ifdef _DNS_DEBUG_ + printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n"); +#endif + return -1; + } + } + + /* Answer section */ + for (i = 0; i < pdhdr->ancount; i++) + { + cp = dns_answer(msg, cp, ip_from_dns); + if(!cp) + { +#ifdef _DNS_DEBUG_ + printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n"); +#endif + return -1; + } + + } + + /* Name server (authority) section */ + for (i = 0; i < pdhdr->nscount; i++) + { + ; + } + + /* Additional section */ + for (i = 0; i < pdhdr->arcount; i++) + { + ; + } + + if(pdhdr->rcode == 0) return 1; // No error + else return 0; +} + + +/* + * MAKE DNS QUERY MESSAGE + * + * Description : This function makes DNS query message. + * Arguments : op - Recursion desired + * name - is a pointer to the domain name. + * buf - is a pointer to the buffer for DNS message. + * len - is the MAX. size of buffer. + * Returns : the pointer to the DNS message. + */ +int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len) +{ + uint8_t *cp; + char *cp1; + char sname[MAXCNAME]; + char *dname; + uint16_t p; + uint16_t dlen; + + cp = buf; + + DNS_MSGID++; + cp = put16(cp, DNS_MSGID); + p = (op << 11) | 0x0100; /* Recursion desired */ + cp = put16(cp, p); + cp = put16(cp, 1); + cp = put16(cp, 0); + cp = put16(cp, 0); + cp = put16(cp, 0); + + strcpy(sname, name); + dname = sname; + dlen = strlen(dname); + for (;;) + { + /* Look for next dot */ + cp1 = strchr(dname, '.'); + + if (cp1 != NULL) len = cp1 - dname; /* More to come */ + else len = dlen; /* Last component */ + + *cp++ = len; /* Write length of component */ + if (len == 0) break; + + /* Copy component up to (but not including) dot */ + memcpy(cp, dname, len); + cp += len; + if (cp1 == NULL) + { + *cp++ = 0; /* Last one; write null and finish */ + break; + } + dname += len+1; + dlen -= len+1; + } + + cp = put16(cp, 0x0001); /* type */ + cp = put16(cp, 0x0001); /* class */ + + return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf))); +} + +/* + * CHECK DNS TIMEOUT + * + * Description : This function check the DNS timeout + * Arguments : None. + * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur + * Note : timeout : retry count and timer both over. + */ + +int8_t check_DNS_timeout(void) +{ + static uint8_t retry_count; + + uint32_t tick = HAL_GetTick(); + if(tick - hal_sys_tick >= DNS_WAIT_TIME * 1000) + { + hal_sys_tick = tick; + if(retry_count >= MAX_DNS_RETRY) { + retry_count = 0; + return -1; // timeout occurred + } + retry_count++; + return 0; // timer over, but no timeout + } + + return 1; // no timer over, no timeout occur +} + + + +/* DNS CLIENT INIT */ +void DNS_init(uint8_t s, uint8_t * buf) +{ + DNS_SOCKET = s; // SOCK_DNS + pDNSMSG = buf; // User's shared buffer + DNS_MSGID = DNS_MSG_ID; +} + +/* DNS CLIENT RUN */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns) +{ + int8_t ret; + struct dhdr dhp; + uint8_t ip[4]; + uint16_t len, port; + int8_t ret_check_timeout; + + hal_sys_tick = HAL_GetTick(); + + // Socket open + WIZCHIP_EXPORT(socket)(DNS_SOCKET, Sn_MR_UDP, 0, 0); + +#ifdef _DNS_DEBUG_ + printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + + len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE); + WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + + while (1) + { + if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0) + { + if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE; + len = WIZCHIP_EXPORT(recvfrom)(DNS_SOCKET, pDNSMSG, len, ip, &port); + #ifdef _DNS_DEBUG_ + printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len); + #endif + ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns); + break; + } + // Check Timeout + ret_check_timeout = check_DNS_timeout(); + if (ret_check_timeout < 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + return 0; // timeout occurred + } + else if (ret_check_timeout == 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Timeout\r\n"); +#endif + WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + } + } + WIZCHIP_EXPORT(close)(DNS_SOCKET); + // Return value + // 0 > : failed / 1 - success + return ret; +} diff --git a/drivers/wiznet5k/internet/dns/dns.h b/drivers/wiznet5k/internet/dns/dns.h new file mode 100644 index 000000000..de0039515 --- /dev/null +++ b/drivers/wiznet5k/internet/dns/dns.h @@ -0,0 +1,96 @@ +//***************************************************************************** +// +//! \file dns.h +//! \brief DNS APIs Header file. +//! \details Send DNS query & Receive DNS reponse. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Move the no reference define to dns.c +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _DNS_H_ +#define _DNS_H_ + +#include +/* + * @brief Define it for Debug & Monitor DNS processing. + * @note If defined, it depends on + */ + +//#define _DNS_DEBUG_ + +#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */ +/* + * @brief Maximum length of your queried Domain name + * @todo SHOULD BE defined it equal as or greater than your Domain name length + null character(1) + * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack. + */ +#define MAX_DOMAIN_NAME 32 // for example "www.google.com" + +#define MAX_DNS_RETRY 2 ///< Requery Count +#define DNS_WAIT_TIME 4 ///< Wait response time. unit 1s. + +#define IPPORT_DOMAIN 53 ///< DNS server port number + +#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modified it any number +/* + * @brief DNS process initialize + * @param s : Socket number for DNS + * @param buf : Buffer for DNS message + */ +void DNS_init(uint8_t s, uint8_t * buf); + +/* + * @brief DNS process + * @details Send DNS query and receive DNS response + * @param dns_ip : DNS server ip address + * @param name : Domain name to be queried + * @param ip_from_dns : IP address from DNS server + * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n + * 0 : failed (Timeout or Parse error)\n + * 1 : success + * @note This function blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME + */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns); + +#endif /* _DNS_H_ */ -- cgit v1.2.3 From 8670215ecc1fcb4b882549b2190af30d22b3c51a Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:17:51 +1000 Subject: Fixups for wiznet 5500 driver --- drivers/wiznet5k/ethernet/socket.c | 3 ++- drivers/wiznet5k/ethernet/wizchip_conf.h | 2 +- drivers/wiznet5k/internet/dns/dns.c | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/wiznet5k/ethernet/socket.c b/drivers/wiznet5k/ethernet/socket.c index ec25fcc79..4ca7113e8 100644 --- a/drivers/wiznet5k/ethernet/socket.c +++ b/drivers/wiznet5k/ethernet/socket.c @@ -286,7 +286,7 @@ int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len) if(tmp & Sn_IR_SENDOK) { setSn_IR(sn, Sn_IR_SENDOK); - #if _WZICHIP_ == 5200 + #if _WIZCHIP_ == 5200 if(getSn_TX_RD(sn) != sock_next_rd[sn]) { setSn_CR(sn,Sn_CR_SEND); @@ -525,6 +525,7 @@ int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_ // read peer's IP address, port number & packet length sock_remained_size[sn] = head[0]; sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; + sock_remained_size[sn] -= 2; // len includes 2 len bytes if(sock_remained_size[sn] > 1514) { WIZCHIP_EXPORT(close)(sn); diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.h b/drivers/wiznet5k/ethernet/wizchip_conf.h index 4a7a7bd69..10f12a794 100644 --- a/drivers/wiznet5k/ethernet/wizchip_conf.h +++ b/drivers/wiznet5k/ethernet/wizchip_conf.h @@ -130,7 +130,7 @@ */ #define _WIZCHIP_IO_BASE_ 0x00000000 // -#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ #ifndef _WIZCHIP_IO_BASE_ #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." #endif diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c index c0ad570c0..daf4db123 100644 --- a/drivers/wiznet5k/internet/dns/dns.c +++ b/drivers/wiznet5k/internet/dns/dns.c @@ -15,6 +15,7 @@ //! 3. Remove the unused define //! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c //! <2013/12/20> V1.1.0 +//! <2018/10/04> Modified HAL_GetTick for use with CircuitPython by Nick Moore //! //! \author Eric Jung & MidnightCow //! \copyright @@ -51,6 +52,7 @@ #include #include +#include "tick.h" //#include "Ethernet/socket.h" //#include "Internet/DNS/dns.h" @@ -121,7 +123,11 @@ uint8_t* pDNSMSG; // DNS message buffer uint8_t DNS_SOCKET; // SOCKET number for DNS uint16_t DNS_MSGID; // DNS message ID -extern uint32_t HAL_GetTick(void); + +uint32_t HAL_GetTick(void) { + return ticks_ms; +} + uint32_t hal_sys_tick; /* converts uint16_t from network buffer to a host byte order integer. */ -- cgit v1.2.3 From 3c32d046bf1fee4d9c84e62a057dae2890f91a94 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:22:09 +1000 Subject: Copy wiznet module across from MicroPython --- shared-bindings/wiznet/__init__.c | 501 ++++++++++++++++++++++++++++++++++++++ shared-module/wiznet/__init__.c | 0 2 files changed, 501 insertions(+) create mode 100644 shared-bindings/wiznet/__init__.c create mode 100644 shared-module/wiznet/__init__.c diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c new file mode 100644 index 000000000..017bd42f8 --- /dev/null +++ b/shared-bindings/wiznet/__init__.c @@ -0,0 +1,501 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "lib/netutils/netutils.h" +#include "modnetwork.h" +#include "pin.h" +#include "spi.h" + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" + +/// \moduleref network + +typedef struct _wiznet5k_obj_t { + mp_obj_base_t base; + mp_uint_t cris_state; + const spi_t *spi; + const pin_obj_t *cs; + const pin_obj_t *rst; + uint8_t socket_used; +} wiznet5k_obj_t; + +STATIC wiznet5k_obj_t wiznet5k_obj; + +STATIC void wiz_cris_enter(void) { + wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); +} + +STATIC void wiz_cris_exit(void) { + MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); +} + +STATIC void wiz_cs_select(void) { + mp_hal_pin_low(wiznet5k_obj.cs); +} + +STATIC void wiz_cs_deselect(void) { + mp_hal_pin_high(wiznet5k_obj.cs); +} + +STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { + HAL_StatusTypeDef status = HAL_SPI_Receive(wiznet5k_obj.spi->spi, buf, len, 5000); + (void)status; +} + +STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { + HAL_StatusTypeDef status = HAL_SPI_Transmit(wiznet5k_obj.spi->spi, (uint8_t*)buf, len, 5000); + (void)status; +} + +STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; + uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); + DNS_init(0, buf); + mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); + m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + if (ret == 1) { + // success + return 0; + } else { + // failure + return -2; + } +} + +STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { + if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + *_errno = MP_EAFNOSUPPORT; + return -1; + } + + switch (socket->u_param.type) { + case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; + case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; + default: *_errno = MP_EINVAL; return -1; + } + + if (socket->u_param.fileno == -1) { + // get first unused socket number + for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { + wiznet5k_obj.socket_used |= (1 << sn); + socket->u_param.fileno = sn; + break; + } + } + if (socket->u_param.fileno == -1) { + // too many open sockets + *_errno = MP_EMFILE; + return -1; + } + } + + // WIZNET does not have a concept of pure "open socket". You need to know + // if it's a server or client at the time of creation of the socket. + // So, we defer the open until we know what kind of socket we want. + + // use "domain" to indicate that this socket has not yet been opened + socket->u_param.domain = 0; + + return 0; +} + +STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { + uint8_t sn = (uint8_t)socket->u_param.fileno; + if (sn < _WIZCHIP_SOCK_NUM_) { + wiznet5k_obj.socket_used &= ~(1 << sn); + WIZCHIP_EXPORT(close)(sn); + } +} + +STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // open the socket in server mode (if port != 0) + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // indicate that this socket has been opened + socket->u_param.domain = 1; + + // success + return 0; +} + +STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { + mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return 0; +} + +STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { + for (;;) { + int sr = getSn_SR((uint8_t)socket->u_param.fileno); + if (sr == SOCK_ESTABLISHED) { + socket2->u_param = socket->u_param; + getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); + *port = getSn_PORT(socket2->u_param.fileno); + + // WIZnet turns the listening socket into the client socket, so we + // need to re-bind and re-listen on another socket for the server. + // TODO handle errors, especially no-more-sockets error + socket->u_param.domain = MOD_NETWORK_AF_INET; + socket->u_param.fileno = -1; + int _errno2; + if (wiznet5k_socket_socket(socket, &_errno2) != 0) { + //printf("(bad resocket %d)\n", _errno2); + } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { + //printf("(bad rebind %d)\n", _errno2); + } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { + //printf("(bad relisten %d)\n", _errno2); + } + + return 0; + } + if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { + wiznet5k_socket_close(socket); + *_errno = MP_ENOTCONN; // ?? + return -1; + } + mp_hal_delay_ms(1); + } +} + +STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + + // now connect + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // success + return 0; +} + +STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { + if (socket->u_param.domain == 0) { + // socket not opened; use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + } + + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { + uint16_t port2; + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); + MP_THREAD_GIL_ENTER(); + *port = port2; + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; +} + +STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; + + /* + if (timeout_ms == 0) { + // set non-blocking mode + uint8_t arg = SOCK_IO_NONBLOCK; + WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); + } + */ +} + +STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + if (request == MP_STREAM_POLL) { + int ret = 0; + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_RD; + } + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_WR; + } + return ret; + } else { + *_errno = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +#if 0 +STATIC void wiznet5k_socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + wiznet5k_socket_obj_t *self = self_in; + print(env, "", self->sn, getSn_MR(self->sn)); +} + +STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { + mp_int_t ret = WIZCHIP_EXPORT(disconnect)(self->sn); + return 0; +} +#endif + +/******************************************************************************/ +// MicroPython bindings + +/// \classmethod \constructor(spi, pin_cs, pin_rst) +/// Create and return a WIZNET5K object. +STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 3, 3, false); + + // init the wiznet5k object + wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; + wiznet5k_obj.cris_state = 0; + wiznet5k_obj.spi = spi_from_mp_obj(args[0]); + wiznet5k_obj.cs = pin_find(args[1]); + wiznet5k_obj.rst = pin_find(args[2]); + wiznet5k_obj.socket_used = 0; + + /*!< SPI configuration */ + SPI_InitTypeDef *init = &wiznet5k_obj.spi->spi->Init; + init->Mode = SPI_MODE_MASTER; + init->Direction = SPI_DIRECTION_2LINES; + init->DataSize = SPI_DATASIZE_8BIT; + init->CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle + init->CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle + init->NSS = SPI_NSS_SOFT; + init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz + init->FirstBit = SPI_FIRSTBIT_MSB; + init->TIMode = SPI_TIMODE_DISABLED; + init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; + init->CRCPolynomial = 7; // unused + spi_init(wiznet5k_obj.spi, false); + + mp_hal_pin_output(wiznet5k_obj.cs); + mp_hal_pin_output(wiznet5k_obj.rst); + + mp_hal_pin_low(wiznet5k_obj.rst); + mp_hal_delay_ms(1); // datasheet says 2us + mp_hal_pin_high(wiznet5k_obj.rst); + mp_hal_delay_ms(160); // datasheet says 150ms + + reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); + reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); + reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); + + uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 2k buffer for each socket + ctlwizchip(CW_INIT_WIZCHIP, sn_size); + + // set some sensible default values; they are configurable using ifconfig method + wiz_NetInfo netinfo = { + .mac = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef}, + .ip = {192, 168, 0, 18}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 0, 1}, + .dns = {8, 8, 8, 8}, // Google public DNS + .dhcp = NETINFO_STATIC, + }; + ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); + + // seems we need a small delay after init + mp_hal_delay_ms(250); + + // register with network module + mod_network_register_nic(&wiznet5k_obj); + + // return wiznet5k object + return &wiznet5k_obj; +} + +/// \method regs() +/// Dump WIZNET5K registers. +STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { + //wiznet5k_obj_t *self = self_in; + printf("Wiz CREG:"); + for (int i = 0; i < 0x50; ++i) { + if (i % 16 == 0) { + printf("\n %04x:", i); + } + #if MICROPY_PY_WIZNET5K == 5200 + uint32_t reg = i; + #else + uint32_t reg = _W5500_IO_BASE_ | i << 8; + #endif + printf(" %02x", WIZCHIP_READ(reg)); + } + for (int sn = 0; sn < 4; ++sn) { + printf("\nWiz SREG[%d]:", sn); + for (int i = 0; i < 0x30; ++i) { + if (i % 16 == 0) { + printf("\n %04x:", i); + } + #if MICROPY_PY_WIZNET5K == 5200 + uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); + #else + uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; + #endif + printf(" %02x", WIZCHIP_READ(reg)); + } + } + printf("\n"); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); + +STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected); + +/// \method ifconfig([(ip, subnet, gateway, dns)]) +/// Get/set IP address, subnet mask, gateway and DNS. +STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { + wiz_NetInfo netinfo; + ctlnetwork(CN_GET_NETINFO, &netinfo); + if (n_args == 1) { + // get + mp_obj_t tuple[4] = { + netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG), + }; + return mp_obj_new_tuple(4, tuple); + } else { + // set + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 4, &items); + netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG); + ctlnetwork(CN_SET_NETINFO, &netinfo); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); + +STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); + +const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { + .base = { + { &mp_type_type }, + .name = MP_QSTR_WIZNET5K, + .make_new = wiznet5k_make_new, + .locals_dict = (mp_obj_dict_t*)&wiznet5k_locals_dict, + }, + .gethostbyname = wiznet5k_gethostbyname, + .socket = wiznet5k_socket_socket, + .close = wiznet5k_socket_close, + .bind = wiznet5k_socket_bind, + .listen = wiznet5k_socket_listen, + .accept = wiznet5k_socket_accept, + .connect = wiznet5k_socket_connect, + .send = wiznet5k_socket_send, + .recv = wiznet5k_socket_recv, + .sendto = wiznet5k_socket_sendto, + .recvfrom = wiznet5k_socket_recvfrom, + .setsockopt = wiznet5k_socket_setsockopt, + .settimeout = wiznet5k_socket_settimeout, + .ioctl = wiznet5k_socket_ioctl, +}; diff --git a/shared-module/wiznet/__init__.c b/shared-module/wiznet/__init__.c new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3 From 27fc84a157b3668c027e38d27297b7922e972639 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:23:24 +1000 Subject: Modify wiznet module for circuitpython --- shared-bindings/wiznet/__init__.c | 97 ++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index 017bd42f8..b1f63e639 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -34,9 +34,14 @@ #include "py/mperrno.h" #include "py/mphal.h" #include "lib/netutils/netutils.h" -#include "modnetwork.h" -#include "pin.h" -#include "spi.h" + +#include "shared-bindings/network/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/random/__init__.h" + +#if MICROPY_PY_WIZNET5K #include "ethernet/wizchip_conf.h" #include "ethernet/socket.h" @@ -47,9 +52,9 @@ typedef struct _wiznet5k_obj_t { mp_obj_base_t base; mp_uint_t cris_state; - const spi_t *spi; - const pin_obj_t *cs; - const pin_obj_t *rst; + busio_spi_obj_t *spi; + digitalio_digitalinout_obj_t cs; + digitalio_digitalinout_obj_t rst; uint8_t socket_used; } wiznet5k_obj_t; @@ -64,21 +69,19 @@ STATIC void wiz_cris_exit(void) { } STATIC void wiz_cs_select(void) { - mp_hal_pin_low(wiznet5k_obj.cs); + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); } STATIC void wiz_cs_deselect(void) { - mp_hal_pin_high(wiznet5k_obj.cs); + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); } STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Receive(wiznet5k_obj.spi->spi, buf, len, 5000); - (void)status; + (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); } STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { - HAL_StatusTypeDef status = HAL_SPI_Transmit(wiznet5k_obj.spi->spi, (uint8_t*)buf, len, 5000); - (void)status; + (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); } STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { @@ -332,6 +335,19 @@ STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { } #endif +void create_random_mac_address(uint8_t *mac) { + uint32_t rb1 = shared_modules_random_getrandbits(24); + uint32_t rb2 = shared_modules_random_getrandbits(24); + // first octet has multicast bit (0) cleared and local bit (1) set + // everything else is just set randomly + mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; + mac[1] = (uint8_t)(rb1 >> 8); + mac[2] = (uint8_t)(rb1); + mac[3] = (uint8_t)(rb2 >> 16); + mac[4] = (uint8_t)(rb2 >> 8); + mac[5] = (uint8_t)(rb2); +} + /******************************************************************************/ // MicroPython bindings @@ -344,32 +360,28 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size // init the wiznet5k object wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = spi_from_mp_obj(args[0]); - wiznet5k_obj.cs = pin_find(args[1]); - wiznet5k_obj.rst = pin_find(args[2]); + wiznet5k_obj.spi = MP_OBJ_TO_PTR(args[0]); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, args[1]); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, args[2]); wiznet5k_obj.socket_used = 0; /*!< SPI configuration */ - SPI_InitTypeDef *init = &wiznet5k_obj.spi->spi->Init; - init->Mode = SPI_MODE_MASTER; - init->Direction = SPI_DIRECTION_2LINES; - init->DataSize = SPI_DATASIZE_8BIT; - init->CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle - init->CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle - init->NSS = SPI_NSS_SOFT; - init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz - init->FirstBit = SPI_FIRSTBIT_MSB; - init->TIMode = SPI_TIMODE_DISABLED; - init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; - init->CRCPolynomial = 7; // unused - spi_init(wiznet5k_obj.spi, false); - - mp_hal_pin_output(wiznet5k_obj.cs); - mp_hal_pin_output(wiznet5k_obj.rst); - - mp_hal_pin_low(wiznet5k_obj.rst); - mp_hal_delay_ms(1); // datasheet says 2us - mp_hal_pin_high(wiznet5k_obj.rst); + // XXX probably should check if the provided SPI is already configured, and + // if so skip configuration? + + common_hal_busio_spi_configure(wiznet5k_obj.spi, + 10000000, // BAUDRATE 10MHz + 1, // HIGH POLARITY + 1, // SECOND PHASE TRANSITION + 8 // 8 BITS + ); + + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL); + + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); + mp_hal_delay_us(10); // datasheet says 2us + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); mp_hal_delay_ms(160); // datasheet says 150ms reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); @@ -381,13 +393,13 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size // set some sensible default values; they are configurable using ifconfig method wiz_NetInfo netinfo = { - .mac = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef}, .ip = {192, 168, 0, 18}, .sn = {255, 255, 255, 0}, .gw = {192, 168, 0, 1}, .dns = {8, 8, 8, 8}, // Google public DNS .dhcp = NETINFO_STATIC, }; + create_random_mac_address(netinfo.mac); ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); // seems we need a small delay after init @@ -499,3 +511,16 @@ const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { .settimeout = wiznet5k_socket_settimeout, .ioctl = wiznet5k_socket_ioctl, }; + +STATIC const mp_rom_map_elem_t mp_module_wiznet_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) }, + { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_wiznet_globals, mp_module_wiznet_globals_table); + +const mp_obj_module_t wiznet_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_wiznet_globals, +}; + +#endif // MICROPY_PY_WIZNET5K -- cgit v1.2.3 From f4c32139f5dd7dbd225d4226fe8d984ec9578859 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:26:01 +1000 Subject: Copy modnetwork and modusocket across from MicroPython --- shared-bindings/network/__init__.c | 93 ++++++++ shared-bindings/network/__init__.h | 83 +++++++ shared-bindings/socket/__init__.c | 468 +++++++++++++++++++++++++++++++++++++ 3 files changed, 644 insertions(+) create mode 100644 shared-bindings/network/__init__.c create mode 100644 shared-bindings/network/__init__.h create mode 100644 shared-bindings/socket/__init__.c diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c new file mode 100644 index 000000000..642174532 --- /dev/null +++ b/shared-bindings/network/__init__.c @@ -0,0 +1,93 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/runtime.h" +#include "modnetwork.h" + +#if MICROPY_PY_NETWORK + +/// \module network - network configuration +/// +/// This module provides network drivers and routing configuration. + +void mod_network_init(void) { + mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); +} + +void mod_network_register_nic(mp_obj_t nic) { + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { + // nic already registered + return; + } + } + // nic not registered so add to list + mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic); +} + +mp_obj_t mod_network_find_nic(const uint8_t *ip) { + // find a NIC that is suited to given IP address + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + // TODO check IP suitability here + //mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + return nic; + } + + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); +} + +STATIC mp_obj_t network_route(void) { + return &MP_STATE_PORT(mod_network_nic_list); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route); + +STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, + + #if MICROPY_PY_WIZNET5K + { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, + #endif + #if MICROPY_PY_CC3K + { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) }, + #endif + + { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table); + +const mp_obj_module_t mp_module_network = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_network_globals, +}; + +#endif // MICROPY_PY_NETWORK diff --git a/shared-bindings/network/__init__.h b/shared-bindings/network/__init__.h new file mode 100644 index 000000000..6796b087a --- /dev/null +++ b/shared-bindings/network/__init__.h @@ -0,0 +1,83 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_STM32_MODNETWORK_H +#define MICROPY_INCLUDED_STM32_MODNETWORK_H + +#define MOD_NETWORK_IPADDR_BUF_SIZE (4) + +#define MOD_NETWORK_AF_INET (2) +#define MOD_NETWORK_AF_INET6 (10) + +#define MOD_NETWORK_SOCK_STREAM (1) +#define MOD_NETWORK_SOCK_DGRAM (2) +#define MOD_NETWORK_SOCK_RAW (3) + +struct _mod_network_socket_obj_t; + +typedef struct _mod_network_nic_type_t { + mp_obj_type_t base; + + // API for non-socket operations + int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out); + + // API for socket operations; return -1 on error + int (*socket)(struct _mod_network_socket_obj_t *socket, int *_errno); + void (*close)(struct _mod_network_socket_obj_t *socket); + int (*bind)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + int (*listen)(struct _mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); + int (*accept)(struct _mod_network_socket_obj_t *socket, struct _mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); + int (*connect)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*send)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*recv)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*sendto)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*recvfrom)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); + int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); + int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); + int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +} mod_network_nic_type_t; + +typedef struct _mod_network_socket_obj_t { + mp_obj_base_t base; + mp_obj_t nic; + mod_network_nic_type_t *nic_type; + union { + struct { + uint8_t domain; + uint8_t type; + int8_t fileno; + } u_param; + mp_uint_t u_state; + }; +} mod_network_socket_obj_t; + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; +extern const mod_network_nic_type_t mod_network_nic_type_cc3k; + +void mod_network_init(void); +void mod_network_register_nic(mp_obj_t nic); +mp_obj_t mod_network_find_nic(const uint8_t *ip); + +#endif // MICROPY_INCLUDED_STM32_MODNETWORK_H diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c new file mode 100644 index 000000000..0c663437e --- /dev/null +++ b/shared-bindings/socket/__init__.c @@ -0,0 +1,468 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "lib/netutils/netutils.h" +#include "modnetwork.h" + +#if MICROPY_PY_USOCKET + +/******************************************************************************/ +// socket class + +STATIC const mp_obj_type_t socket_type; + +// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 4, false); + + // create socket object (not bound to any NIC yet) + mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); + s->base.type = (mp_obj_t)&socket_type; + s->nic = MP_OBJ_NULL; + s->nic_type = NULL; + s->u_param.domain = MOD_NETWORK_AF_INET; + s->u_param.type = MOD_NETWORK_SOCK_STREAM; + s->u_param.fileno = -1; + if (n_args >= 1) { + s->u_param.domain = mp_obj_get_int(args[0]); + if (n_args >= 2) { + s->u_param.type = mp_obj_get_int(args[1]); + if (n_args >= 4) { + s->u_param.fileno = mp_obj_get_int(args[3]); + } + } + } + + return s; +} + +STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { + if (self->nic == MP_OBJ_NULL) { + // select NIC based on IP + self->nic = mod_network_find_nic(ip); + self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic); + + // call the NIC to open the socket + int _errno; + if (self->nic_type->socket(self, &_errno) != 0) { + mp_raise_OSError(_errno); + } + } +} + +// method socket.bind(address) +STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = self_in; + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to bind the socket + int _errno; + if (self->nic_type->bind(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); + +// method socket.listen(backlog) +STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { + mod_network_socket_obj_t *self = self_in; + + if (self->nic == MP_OBJ_NULL) { + // not connected + // TODO I think we can listen even if not bound... + mp_raise_OSError(MP_ENOTCONN); + } + + int _errno; + if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); + +// method socket.accept() +STATIC mp_obj_t socket_accept(mp_obj_t self_in) { + mod_network_socket_obj_t *self = self_in; + + // create new socket object + // starts with empty NIC so that finaliser doesn't run close() method if accept() fails + mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); + socket2->base.type = (mp_obj_t)&socket_type; + socket2->nic = MP_OBJ_NULL; + socket2->nic_type = NULL; + + // accept incoming connection + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port; + int _errno; + if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + // new socket has valid state, so set the NIC to the same as parent + socket2->nic = self->nic; + socket2->nic_type = self->nic_type; + + // make the return value + mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL); + client->items[0] = socket2; + client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + + return client; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); + +// method socket.connect(address) +STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = self_in; + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to connect the socket + int _errno; + if (self->nic_type->connect(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); + +// method socket.send(bytes) +STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { + mod_network_socket_obj_t *self = self_in; + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_EPIPE); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + int _errno; + mp_uint_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); + +// method socket.recv(bufsize) +STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = self_in; + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_int_t len = mp_obj_get_int(len_in); + vstr_t vstr; + vstr_init_len(&vstr, len); + int _errno; + mp_uint_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + if (ret == 0) { + return mp_const_empty_bytes; + } + vstr.len = ret; + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); + +// method socket.sendto(bytes, address) +STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = self_in; + + // get the data + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to sendto + int _errno; + mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + + return mp_obj_new_int(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); + +// method socket.recvfrom(bufsize) +STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = self_in; + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + vstr_t vstr; + vstr_init_len(&vstr, mp_obj_get_int(len_in)); + byte ip[4]; + mp_uint_t port; + int _errno; + mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + mp_obj_t tuple[2]; + if (ret == 0) { + tuple[0] = mp_const_empty_bytes; + } else { + vstr.len = ret; + tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + } + tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); + +// method socket.setsockopt(level, optname, value) +STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { + mod_network_socket_obj_t *self = args[0]; + + mp_int_t level = mp_obj_get_int(args[1]); + mp_int_t opt = mp_obj_get_int(args[2]); + + const void *optval; + mp_uint_t optlen; + mp_int_t val; + if (mp_obj_is_integer(args[3])) { + val = mp_obj_get_int_truncated(args[3]); + optval = &val; + optlen = sizeof(val); + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + optval = bufinfo.buf; + optlen = bufinfo.len; + } + + int _errno; + if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt); + +// method socket.settimeout(value) +// timeout=0 means non-blocking +// timeout=None means blocking +// otherwise, timeout is in seconds +STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { + mod_network_socket_obj_t *self = self_in; + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_uint_t timeout; + if (timeout_in == mp_const_none) { + timeout = -1; + } else { + #if MICROPY_PY_BUILTINS_FLOAT + timeout = 1000 * mp_obj_get_float(timeout_in); + #else + timeout = 1000 * mp_obj_get_int(timeout_in); + #endif + } + int _errno; + if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { + mp_raise_OSError(_errno); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout); + +// method socket.setblocking(flag) +STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { + if (mp_obj_is_true(blocking)) { + return socket_settimeout(self_in, mp_const_none); + } else { + return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); + +STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) }, + { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) }, + { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); + +mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + mod_network_socket_obj_t *self = self_in; + if (request == MP_STREAM_CLOSE) { + if (self->nic != MP_OBJ_NULL) { + self->nic_type->close(self); + self->nic = MP_OBJ_NULL; + } + return 0; + } + return self->nic_type->ioctl(self, request, arg, errcode); +} + +STATIC const mp_stream_p_t socket_stream_p = { + .ioctl = socket_ioctl, + .is_text = false, +}; + +STATIC const mp_obj_type_t socket_type = { + { &mp_type_type }, + .name = MP_QSTR_socket, + .make_new = socket_make_new, + .protocol = &socket_stream_p, + .locals_dict = (mp_obj_dict_t*)&socket_locals_dict, +}; + +/******************************************************************************/ +// usocket module + +// function usocket.getaddrinfo(host, port) +STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { + size_t hlen; + const char *host = mp_obj_str_get_data(host_in, &hlen); + mp_int_t port = mp_obj_get_int(port_in); + uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + bool have_ip = false; + + if (hlen > 0) { + // check if host is already in IP form + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); + have_ip = true; + nlr_pop(); + } else { + // swallow exception: host was not in IP form so need to do DNS lookup + } + } + + if (!have_ip) { + // find a NIC that can do a name lookup + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->gethostbyname != NULL) { + int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); + if (ret != 0) { + mp_raise_OSError(ret); + } + have_ip = true; + break; + } + } + } + + if (!have_ip) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); + } + + mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); + return mp_obj_new_list(1, (mp_obj_t*)&tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo); + +STATIC const mp_rom_map_elem_t mp_module_usocket_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) }, + + { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) }, + { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&mod_usocket_getaddrinfo_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) }, + { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) }, + + { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) }, + + /* + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) }, + */ +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_usocket_globals, mp_module_usocket_globals_table); + +const mp_obj_module_t mp_module_usocket = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_usocket_globals, +}; + +#endif // MICROPY_PY_USOCKET -- cgit v1.2.3 From d33f6214f15d1983c2fa7f54f42d2145e656fa22 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:30:26 +1000 Subject: modify modnetwork and modusocket for circuitpython --- shared-bindings/network/__init__.c | 32 +++++++++------- shared-bindings/network/__init__.h | 7 ++-- shared-bindings/socket/__init__.c | 75 ++++++++++++++++++++------------------ shared-module/network/__init__.c | 0 shared-module/socket/__init__.c | 0 5 files changed, 62 insertions(+), 52 deletions(-) create mode 100644 shared-module/network/__init__.c create mode 100644 shared-module/socket/__init__.c diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index 642174532..357aad346 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -30,7 +30,11 @@ #include "py/objlist.h" #include "py/runtime.h" -#include "modnetwork.h" +#include "py/mphal.h" +#include "py/mperrno.h" +#include "lib/netutils/netutils.h" + +#include "shared-bindings/network/__init__.h" #if MICROPY_PY_NETWORK @@ -42,6 +46,9 @@ void mod_network_init(void) { mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); } +void mod_network_deinit(void) { +} + void mod_network_register_nic(mp_obj_t nic) { for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { @@ -50,7 +57,7 @@ void mod_network_register_nic(mp_obj_t nic) { } } // nic not registered so add to list - mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic); + mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic); } mp_obj_t mod_network_find_nic(const uint8_t *ip) { @@ -62,30 +69,29 @@ mp_obj_t mod_network_find_nic(const uint8_t *ip) { return nic; } - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); } +STATIC mp_obj_t network_initialize(void) { + mod_network_init(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_initialize_obj, network_initialize); + STATIC mp_obj_t network_route(void) { - return &MP_STATE_PORT(mod_network_nic_list); + return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route); STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, - - #if MICROPY_PY_WIZNET5K - { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, - #endif - #if MICROPY_PY_CC3K - { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) }, - #endif - + { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&network_initialize_obj) }, { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table); -const mp_obj_module_t mp_module_network = { +const mp_obj_module_t network_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&mp_module_network_globals, }; diff --git a/shared-bindings/network/__init__.h b/shared-bindings/network/__init__.h index 6796b087a..1036c47be 100644 --- a/shared-bindings/network/__init__.h +++ b/shared-bindings/network/__init__.h @@ -23,8 +23,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_MODNETWORK_H -#define MICROPY_INCLUDED_STM32_MODNETWORK_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H #define MOD_NETWORK_IPADDR_BUF_SIZE (4) @@ -77,7 +77,8 @@ extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; extern const mod_network_nic_type_t mod_network_nic_type_cc3k; void mod_network_init(void); +void mod_network_deinit(void); void mod_network_register_nic(mp_obj_t nic); mp_obj_t mod_network_find_nic(const uint8_t *ip); -#endif // MICROPY_INCLUDED_STM32_MODNETWORK_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index 0c663437e..b378b2940 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,12 +34,17 @@ #include "py/stream.h" #include "py/mperrno.h" #include "lib/netutils/netutils.h" -#include "modnetwork.h" -#if MICROPY_PY_USOCKET +#include "shared-bindings/network/__init__.h" -/******************************************************************************/ -// socket class +//| :mod:`socket` --- TCP, UDP and RAW socket support +//| ================================================= +//| +//| .. module:: socket +//| :synopsis: TCP, UDP and RAW sockets +//| :platform: SAMD21, SAMD51 +//| +//| XXX TODO Write Docs. STATIC const mp_obj_type_t socket_type; @@ -48,7 +54,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t // create socket object (not bound to any NIC yet) mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); - s->base.type = (mp_obj_t)&socket_type; + s->base.type = &socket_type; s->nic = MP_OBJ_NULL; s->nic_type = NULL; s->u_param.domain = MOD_NETWORK_AF_INET; @@ -64,7 +70,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t } } - return s; + return MP_OBJ_FROM_PTR(s); } STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { @@ -83,7 +89,7 @@ STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { // method socket.bind(address) STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); // get address uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; @@ -104,7 +110,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); // method socket.listen(backlog) STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { // not connected @@ -123,12 +129,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); // method socket.accept() STATIC mp_obj_t socket_accept(mp_obj_t self_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); // create new socket object // starts with empty NIC so that finaliser doesn't run close() method if accept() fails mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); - socket2->base.type = (mp_obj_t)&socket_type; + socket2->base.type = &socket_type; socket2->nic = MP_OBJ_NULL; socket2->nic_type = NULL; @@ -145,17 +151,17 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) { socket2->nic_type = self->nic_type; // make the return value - mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL); - client->items[0] = socket2; + mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + client->items[0] = MP_OBJ_FROM_PTR(socket2); client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return client; + return MP_OBJ_FROM_PTR(client); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); // method socket.connect(address) STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); // get address uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; @@ -176,7 +182,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); // method socket.send(bytes) STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { // not connected mp_raise_OSError(MP_EPIPE); @@ -184,7 +190,7 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); int _errno; - mp_uint_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); + mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); if (ret == -1) { mp_raise_OSError(_errno); } @@ -194,7 +200,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); // method socket.recv(bufsize) STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { // not connected mp_raise_OSError(MP_ENOTCONN); @@ -203,7 +209,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { vstr_t vstr; vstr_init_len(&vstr, len); int _errno; - mp_uint_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno); + mp_int_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno); if (ret == -1) { mp_raise_OSError(_errno); } @@ -217,7 +223,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); // method socket.sendto(bytes, address) STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); // get the data mp_buffer_info_t bufinfo; @@ -243,7 +249,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); // method socket.recvfrom(bufsize) STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { // not connected mp_raise_OSError(MP_ENOTCONN); @@ -271,7 +277,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); // method socket.setsockopt(level, optname, value) STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { - mod_network_socket_obj_t *self = args[0]; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_int_t level = mp_obj_get_int(args[1]); mp_int_t opt = mp_obj_get_int(args[2]); @@ -304,7 +310,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_s // timeout=None means blocking // otherwise, timeout is in seconds STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { - mod_network_socket_obj_t *self = self_in; + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { // not connected mp_raise_OSError(MP_ENOTCONN); @@ -355,8 +361,8 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); -mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { - mod_network_socket_obj_t *self = self_in; +mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (request == MP_STREAM_CLOSE) { if (self->nic != MP_OBJ_NULL) { self->nic_type->close(self); @@ -383,8 +389,7 @@ STATIC const mp_obj_type_t socket_type = { /******************************************************************************/ // usocket module -// function usocket.getaddrinfo(host, port) -STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { +STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { size_t hlen; const char *host = mp_obj_str_get_data(host_in, &hlen); mp_int_t port = mp_obj_get_int(port_in); @@ -420,10 +425,10 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { } if (!have_ip) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); } - mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL); + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); @@ -431,13 +436,13 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); return mp_obj_new_list(1, (mp_obj_t*)&tuple); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_getaddrinfo_obj, socket_getaddrinfo); -STATIC const mp_rom_map_elem_t mp_module_usocket_globals_table[] = { +STATIC const mp_rom_map_elem_t socket_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) }, { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) }, - { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&mod_usocket_getaddrinfo_obj) }, + { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socket_getaddrinfo_obj) }, // class constants { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) }, @@ -458,11 +463,9 @@ STATIC const mp_rom_map_elem_t mp_module_usocket_globals_table[] = { */ }; -STATIC MP_DEFINE_CONST_DICT(mp_module_usocket_globals, mp_module_usocket_globals_table); +STATIC MP_DEFINE_CONST_DICT(socket_globals, socket_globals_table); -const mp_obj_module_t mp_module_usocket = { +const mp_obj_module_t socket_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&mp_module_usocket_globals, + .globals = (mp_obj_dict_t*)&socket_globals, }; - -#endif // MICROPY_PY_USOCKET diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/socket/__init__.c b/shared-module/socket/__init__.c new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3 From f9bda0ff93ef1211c84cbca02b76ae58bef60767 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 21:59:25 +1000 Subject: Makefile & mpconfigport for atmel-samd with wiznet --- ports/atmel-samd/Makefile | 29 ++++++++++++++++++++++-- ports/atmel-samd/mpconfigport.h | 48 ++++++++++++++++++++++++++++++++++++++-- ports/atmel-samd/mpconfigport.mk | 3 +++ 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index f8e5051c2..f01704a81 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -123,7 +123,6 @@ endif CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) - ifeq ($(CHIP_FAMILY), samd21) CFLAGS += \ -mthumb \ @@ -287,6 +286,25 @@ SRC_C = \ freetouch/adafruit_ptc.c \ supervisor/shared/memory.c +ifeq ($(MICROPY_PY_NETWORK),1) +CFLAGS += -DMICROPY_PY_NETWORK=1 + +SRC_MOD += lib/netutils/netutils.c + +ifneq ($(MICROPY_PY_WIZNET5K),0) +WIZNET5K_DIR=drivers/wiznet5k +INC += -I$(TOP)/$(WIZNET5K_DIR) +CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K) +SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ + ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \ + ethernet/wizchip_conf.c \ + ethernet/socket.c \ + internet/dns/dns.c \ + ) + +endif # MICROPY_PY_WIZNET5K +endif # MICROPY_PY_NETWORK + # Choose which flash filesystem impl to use. # (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive. # But that might not be true in the future.) @@ -362,7 +380,6 @@ SRC_LIBM = $(addprefix lib/,\ ) endif - # These don't have corresponding files in each port but are still located in # shared-bindings to make it clear what the contents of the modules are. SRC_BINDINGS_ENUMS = \ @@ -401,6 +418,13 @@ SRC_SHARED_MODULE = \ uheap/__init__.c \ ustack/__init__.c +ifeq ($(MICROPY_PY_NETWORK),1) +SRC_SHARED_MODULE += socket/__init__.c network/__init__.c +ifneq ($(MICROPY_PY_WIZNET5K),0) +SRC_SHARED_MODULE += wiznet/__init__.c +endif +endif + # SAMRs don't have a DAC ifneq ($(CHIP_VARIANT),SAMR21G18A) SRC_COMMON_HAL += \ @@ -441,6 +465,7 @@ ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(STM_SRC_C) # Sources that only hold QSTRs after pre-processing. diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 14f72ccfb..18fc0ccb3 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -67,6 +67,18 @@ #define MICROPY_FLOAT_HIGH_QUALITY_HASH (1) #define MICROPY_STREAMS_NON_BLOCK (1) +#ifndef MICROPY_PY_NETWORK +#define MICROPY_PY_NETWORK (0) +#endif + +#ifndef MICROPY_PY_WIZNET5K +#define MICROPY_PY_WIZNET5K (0) +#endif + +#ifndef MICROPY_PY_CC3K +#define MICROPY_PY_CC3K (0) +#endif + // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ @@ -84,6 +96,7 @@ #define MICROPY_VFS (1) #define MICROPY_VFS_FAT (1) #define MICROPY_PY_MACHINE (1) +#define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HW_ENABLE_DAC (1) @@ -121,6 +134,9 @@ typedef unsigned mp_uint_t; // must be pointer size typedef long mp_off_t; +// XXX check we don't need this +#define MICROPY_THREAD_YIELD() + #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) #define mp_type_fileio mp_type_vfs_fat_fileio @@ -194,6 +210,9 @@ extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t stage_module; extern const struct _mp_obj_module_t touchio_module; extern const struct _mp_obj_module_t usb_hid_module; +extern const struct _mp_obj_module_t network_module; +extern const struct _mp_obj_module_t socket_module; +extern const struct _mp_obj_module_t wiznet_module; // Internal flash size dependent settings. #if BOARD_FLASH_SIZE > 192000 @@ -234,11 +253,26 @@ extern const struct _mp_obj_module_t usb_hid_module; #endif #ifdef CIRCUITPY_DISPLAYIO - #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, + #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #else - #define DISPLAYIO_MODULE + #define DISPLAYIO_MODULE #endif + #if MICROPY_PY_NETWORK + #define NETWORK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, + #define SOCKET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_module }, + #if MICROPY_PY_WIZNET5K + #define WIZNET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_wiznet), (mp_obj_t)&wiznet_module }, + #else + #define WIZNET_MODULE + #endif + #else + #define NETWORK_MODULE + #define SOCKET_MODULE + #define WIZNET_MODULE + #endif + + #ifndef EXTRA_BUILTIN_MODULES #define EXTRA_BUILTIN_MODULES \ AUDIOIO_MODULE \ @@ -246,6 +280,9 @@ extern const struct _mp_obj_module_t usb_hid_module; { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \ DISPLAYIO_MODULE \ I2CSLAVE_MODULE \ + NETWORK_MODULE \ + SOCKET_MODULE \ + WIZNET_MODULE \ { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module } #endif @@ -345,6 +382,12 @@ extern const struct _mp_obj_module_t usb_hid_module; #include "peripherals/samd/dma.h" +#if MICROPY_PY_NETWORK + #define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list; +#else + #define NETWORK_ROOT_POINTERS +#endif + #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ vstr_t *repl_line; \ @@ -352,6 +395,7 @@ extern const struct _mp_obj_module_t usb_hid_module; mp_obj_t rtc_time_source; \ FLASH_ROOT_POINTERS \ mp_obj_t gamepad_singleton; \ + NETWORK_ROOT_POINTERS \ void run_background_tasks(void); #define MICROPY_VM_HOOK_LOOP run_background_tasks(); diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index c2eedfdc3..bc3acebb9 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -16,3 +16,6 @@ endif INTERNAL_LIBM = 1 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 -- cgit v1.2.3 From 15b59bee1b04323365da58338a6a70f9dd51fc79 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 4 Oct 2018 22:31:47 +1000 Subject: change initialization method + mod_network names --- main.c | 12 +++++++++++- ports/atmel-samd/mpconfigport.h | 1 - shared-bindings/network/__init__.c | 15 ++++----------- shared-bindings/network/__init__.h | 8 ++++---- shared-bindings/socket/__init__.c | 2 +- shared-bindings/wiznet/__init__.c | 2 +- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/main.c b/main.c index 1e07b2d07..f1c68d06a 100755 --- a/main.c +++ b/main.c @@ -54,6 +54,10 @@ #include "supervisor/shared/stack.h" #include "supervisor/serial.h" +#ifdef MICROPY_PY_NETWORK +#include "shared-bindings/network/__init__.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -108,10 +112,16 @@ void start_mp(supervisor_allocation* heap) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); mp_obj_list_init(mp_sys_argv, 0); + + #if MICROPY_PY_NETWORK + network_module_init(); + #endif } void stop_mp(void) { - + #if MICROPY_PY_NETWORK + network_module_deinit(); + #endif } #define STRING_LIST(...) {__VA_ARGS__, ""} diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 18fc0ccb3..20a2b6726 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -96,7 +96,6 @@ #define MICROPY_VFS (1) #define MICROPY_VFS_FAT (1) #define MICROPY_PY_MACHINE (1) -#define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HW_ENABLE_DAC (1) diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index 357aad346..ad42fea5f 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -42,14 +42,14 @@ /// /// This module provides network drivers and routing configuration. -void mod_network_init(void) { +void network_module_init(void) { mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); } -void mod_network_deinit(void) { +void network_module_deinit(void) { } -void mod_network_register_nic(mp_obj_t nic) { +void network_module_register_nic(mp_obj_t nic) { for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { // nic already registered @@ -60,7 +60,7 @@ void mod_network_register_nic(mp_obj_t nic) { mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic); } -mp_obj_t mod_network_find_nic(const uint8_t *ip) { +mp_obj_t network_module_find_nic(const uint8_t *ip) { // find a NIC that is suited to given IP address for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; @@ -72,12 +72,6 @@ mp_obj_t mod_network_find_nic(const uint8_t *ip) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); } -STATIC mp_obj_t network_initialize(void) { - mod_network_init(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_initialize_obj, network_initialize); - STATIC mp_obj_t network_route(void) { return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)); } @@ -85,7 +79,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route); STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, - { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&network_initialize_obj) }, { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) }, }; diff --git a/shared-bindings/network/__init__.h b/shared-bindings/network/__init__.h index 1036c47be..b3fd657b6 100644 --- a/shared-bindings/network/__init__.h +++ b/shared-bindings/network/__init__.h @@ -76,9 +76,9 @@ typedef struct _mod_network_socket_obj_t { extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; extern const mod_network_nic_type_t mod_network_nic_type_cc3k; -void mod_network_init(void); -void mod_network_deinit(void); -void mod_network_register_nic(mp_obj_t nic); -mp_obj_t mod_network_find_nic(const uint8_t *ip); +void network_module_init(void); +void network_module_deinit(void); +void network_module_register_nic(mp_obj_t nic); +mp_obj_t network_module_find_nic(const uint8_t *ip); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index b378b2940..85796c5c4 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -76,7 +76,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { if (self->nic == MP_OBJ_NULL) { // select NIC based on IP - self->nic = mod_network_find_nic(ip); + self->nic = network_module_find_nic(ip); self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic); // call the NIC to open the socket diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index b1f63e639..717ef4bc6 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -406,7 +406,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size mp_hal_delay_ms(250); // register with network module - mod_network_register_nic(&wiznet5k_obj); + network_module_register_nic(&wiznet5k_obj); // return wiznet5k object return &wiznet5k_obj; -- cgit v1.2.3 From 661743ebffd7838b8a45010cf2e8c1d928763427 Mon Sep 17 00:00:00 2001 From: Pedro Filipe Date: Thu, 4 Oct 2018 22:55:28 -0300 Subject: String internationalization for Brazilian Portuguese --- locale/pt_BR.po | 152 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index d6b283c9f..0a05d3db7 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -511,48 +511,48 @@ msgstr "Bits de parada inválidos" #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 msgid "ESP8266 does not support pull down." -msgstr "" +msgstr "ESP8266 não suporta pull down." #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 msgid "GPIO16 does not support pull up." -msgstr "" +msgstr "GPIO16 não suporta pull up." #: ports/esp8266/common-hal/microcontroller/__init__.c:66 msgid "ESP8226 does not support safe mode." -msgstr "" +msgstr "O ESP8226 não suporta o modo de segurança." #: ports/esp8266/common-hal/pulseio/PWMOut.c:54 #: ports/esp8266/common-hal/pulseio/PWMOut.c:113 #, c-format msgid "Maximum PWM frequency is %dhz." -msgstr "" +msgstr "A frequência máxima PWM é de %dhz." #: ports/esp8266/common-hal/pulseio/PWMOut.c:57 #: ports/esp8266/common-hal/pulseio/PWMOut.c:116 msgid "Minimum PWM frequency is 1hz." -msgstr "" +msgstr "A frequência mínima PWM é de 1hz" #: ports/esp8266/common-hal/pulseio/PWMOut.c:68 #, c-format msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." -msgstr "" +msgstr "Múltiplas frequências PWM não suportadas. PWM já definido para %dhz." #: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 #, c-format msgid "PWM not supported on pin %d" -msgstr "" +msgstr "PWM não suportado no pino %d" #: ports/esp8266/common-hal/pulseio/PulseIn.c:78 msgid "No PulseIn support for %q" -msgstr "" +msgstr "Não há suporte para PulseIn no pino %q" #: ports/esp8266/common-hal/storage/__init__.c:34 msgid "Unable to remount filesystem" -msgstr "" +msgstr "Não é possível remontar o sistema de arquivos" #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "" +msgstr "Use o esptool para apagar o flash e recarregar o Python" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" @@ -561,155 +561,155 @@ msgstr "" #: ports/esp8266/machine_adc.c:57 #, c-format msgid "not a valid ADC Channel: %d" -msgstr "" +msgstr "não é um canal ADC válido: %d" #: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 msgid "impossible baudrate" -msgstr "" +msgstr "taxa de transmissão impossível" #: ports/esp8266/machine_pin.c:129 msgid "expecting a pin" -msgstr "" +msgstr "esperando um pino" #: ports/esp8266/machine_pin.c:284 msgid "Pin(16) doesn't support pull" -msgstr "" +msgstr "Pino (16) não suporta pull" #: ports/esp8266/machine_pin.c:323 msgid "invalid pin" -msgstr "" +msgstr "Pino inválido" #: ports/esp8266/machine_pin.c:389 msgid "pin does not have IRQ capabilities" -msgstr "" +msgstr "Pino não tem recursos de IRQ" #: ports/esp8266/machine_rtc.c:185 msgid "buffer too long" -msgstr "" +msgstr "buffer muito longo" #: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 #: ports/esp8266/machine_rtc.c:246 msgid "invalid alarm" -msgstr "" +msgstr "Alarme inválido" #: ports/esp8266/machine_uart.c:169 #, c-format msgid "UART(%d) does not exist" -msgstr "" +msgstr "UART(%d) não existe" #: ports/esp8266/machine_uart.c:219 msgid "UART(1) can't read" -msgstr "" +msgstr "UART(1) não pode ler" #: ports/esp8266/modesp.c:119 msgid "len must be multiple of 4" -msgstr "" +msgstr "len deve ser múltiplo de 4" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "" +msgstr "alocação de memória falhou, alocando %u bytes para código nativo" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" -msgstr "" +msgstr "o local do flash deve estar abaixo de 1 MByte" #: ports/esp8266/modmachine.c:63 msgid "frequency can only be either 80Mhz or 160MHz" -msgstr "" +msgstr "A frequência só pode ser 80Mhz ou 160MHz" #: ports/esp8266/modnetwork.c:61 msgid "AP required" -msgstr "" +msgstr "AP requerido" #: ports/esp8266/modnetwork.c:61 msgid "STA required" -msgstr "" +msgstr "STA requerido" #: ports/esp8266/modnetwork.c:87 msgid "Cannot update i/f status" -msgstr "" +msgstr "Não é possível atualizar o status i/f" #: ports/esp8266/modnetwork.c:142 msgid "Cannot set STA config" -msgstr "" +msgstr "Não é possível definir a configuração STA" #: ports/esp8266/modnetwork.c:144 msgid "Cannot connect to AP" -msgstr "" +msgstr "Não é possível conectar-se ao AP" #: ports/esp8266/modnetwork.c:152 msgid "Cannot disconnect from AP" -msgstr "" +msgstr "Não é possível desconectar do AP" #: ports/esp8266/modnetwork.c:173 msgid "unknown status param" -msgstr "" +msgstr "parâmetro de status desconhecido" #: ports/esp8266/modnetwork.c:222 msgid "STA must be active" -msgstr "" +msgstr "STA deve estar ativo" #: ports/esp8266/modnetwork.c:239 msgid "scan failed" -msgstr "" +msgstr "varredura falhou" #: ports/esp8266/modnetwork.c:306 msgid "wifi_set_ip_info() failed" -msgstr "" +msgstr "wifi_set_ip_info() falhou" #: ports/esp8266/modnetwork.c:319 msgid "either pos or kw args are allowed" -msgstr "" +msgstr "pos ou kw args são permitidos" #: ports/esp8266/modnetwork.c:329 msgid "can't get STA config" -msgstr "" +msgstr "não pode obter a configuração STA" #: ports/esp8266/modnetwork.c:331 msgid "can't get AP config" -msgstr "" +msgstr "não pode obter configuração de AP" #: ports/esp8266/modnetwork.c:346 msgid "invalid buffer length" -msgstr "" +msgstr "comprimento de buffer inválido" #: ports/esp8266/modnetwork.c:405 msgid "can't set STA config" -msgstr "" +msgstr "não é possível definir a configuração STA" #: ports/esp8266/modnetwork.c:407 msgid "can't set AP config" -msgstr "" +msgstr "não é possível definir a configuração do AP" #: ports/esp8266/modnetwork.c:416 msgid "can query only one param" -msgstr "" +msgstr "pode consultar apenas um parâmetro" #: ports/esp8266/modnetwork.c:469 msgid "unknown config param" -msgstr "" +msgstr "parâmetro configuração desconhecido" #: ports/nrf/common-hal/analogio/AnalogOut.c:37 msgid "AnalogOut functionality not supported" -msgstr "" +msgstr "Funcionalidade AnalogOut não suportada" #: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" -msgstr "" +msgstr "Todos os periféricos I2C estão em uso" #: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" -msgstr "" +msgstr "Todos os periféricos SPI estão em uso" #: ports/nrf/common-hal/busio/SPI.c:176 msgid "Baud rate too high for this SPI peripheral" -msgstr "" +msgstr "Taxa de transmissão muito alta para esse periférico SPI" #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" -msgstr "" +msgstr "erro = 0x%08lX" #: ports/nrf/common-hal/busio/UART.c:86 #, fuzzy @@ -727,41 +727,41 @@ msgstr "I2C operação não suportada" #: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 #: ports/nrf/common-hal/busio/UART.c:364 msgid "busio.UART not available" -msgstr "" +msgstr "busio.UART não disponível" #: ports/nrf/common-hal/microcontroller/Processor.c:49 #, c-format msgid "Can not get temperature. status: 0x%02x" -msgstr "" +msgstr "Não pode obter a temperatura. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." -msgstr "" +msgstr "Não é possível aplicar parâmetros GAP." #: ports/nrf/drivers/bluetooth/ble_drv.c:213 msgid "Cannot set PPCP parameters." -msgstr "" +msgstr "Não é possível definir parâmetros PPCP." #: ports/nrf/drivers/bluetooth/ble_drv.c:245 msgid "Can not query for the device address." -msgstr "" +msgstr "Não é possível consultar o endereço do dispositivo." #: ports/nrf/drivers/bluetooth/ble_drv.c:264 msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "" +msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor." #: ports/nrf/drivers/bluetooth/ble_drv.c:284 #: ports/nrf/drivers/bluetooth/ble_drv.c:298 msgid "Can not add Service." -msgstr "" +msgstr "Não é possível adicionar o serviço." #: ports/nrf/drivers/bluetooth/ble_drv.c:373 msgid "Can not add Characteristic." -msgstr "" +msgstr "Não é possível adicionar Característica." #: ports/nrf/drivers/bluetooth/ble_drv.c:400 msgid "Can not apply device name in the stack." -msgstr "" +msgstr "Não é possível aplicar o nome do dispositivo na pilha." #: ports/nrf/drivers/bluetooth/ble_drv.c:464 #: ports/nrf/drivers/bluetooth/ble_drv.c:514 @@ -771,39 +771,39 @@ msgstr "" #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 msgid "Can encode UUID into the advertisement packet." -msgstr "" +msgstr "Pode codificar o UUID no pacote de anúncios." #: ports/nrf/drivers/bluetooth/ble_drv.c:545 msgid "Can not fit data into the advertisement packet." -msgstr "" +msgstr "Não é possível ajustar dados no pacote de anúncios." #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "" +msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format msgid "Can not start advertisement. status: 0x%02x" -msgstr "" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format msgid "Can not stop advertisement. status: 0x%02x" -msgstr "" +msgstr "Não pode parar propaganda. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 #: ports/nrf/drivers/bluetooth/ble_drv.c:726 #, c-format msgid "Can not read attribute value. status: 0x%02x" -msgstr "" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:667 #: ports/nrf/drivers/bluetooth/ble_drv.c:756 #, c-format msgid "Can not write attribute value. status: 0x%02x" -msgstr "" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:691 #, c-format @@ -825,11 +825,11 @@ msgstr "" #: ports/nrf/modules/ubluepy/ubluepy_service.c:132 #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 msgid "Invalid UUID parameter" -msgstr "" +msgstr "Parâmetro UUID inválido" #: ports/nrf/modules/ubluepy/ubluepy_service.c:73 msgid "Invalid Service type" -msgstr "" +msgstr "Tipo de serviço inválido" #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 msgid "Invalid UUID string length" @@ -837,19 +837,19 @@ msgstr "" #: ports/unix/modffi.c:138 msgid "Unknown type" -msgstr "" +msgstr "Tipo desconhecido" #: ports/unix/modffi.c:207 ports/unix/modffi.c:265 msgid "Error in ffi_prep_cif" -msgstr "" +msgstr "Erro no ffi_prep_cif" #: ports/unix/modffi.c:270 msgid "ffi_prep_closure_loc" -msgstr "" +msgstr "ffi_prep_closure_loc" #: ports/unix/modffi.c:413 msgid "Don't know how to pass object to native function" -msgstr "" +msgstr "Não sabe como passar o objeto para a função nativa" #: ports/unix/modusocket.c:474 #, c-format @@ -858,34 +858,34 @@ msgstr "" #: py/argcheck.c:44 msgid "function does not take keyword arguments" -msgstr "" +msgstr "função não aceita argumentos de palavras-chave" #: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 #, c-format msgid "function takes %d positional arguments but %d were given" -msgstr "" +msgstr "função leva %d argumentos posicionais, mas apenas %d foram passadas" #: py/argcheck.c:64 #, c-format msgid "function missing %d required positional arguments" -msgstr "" +msgstr "função ausente %d requer argumentos posicionais" #: py/argcheck.c:72 #, c-format msgid "function expected at most %d arguments, got %d" -msgstr "" +msgstr "função esperada na maioria dos %d argumentos, obteve %d" #: py/argcheck.c:97 msgid "'%q' argument required" -msgstr "" +msgstr "'%q' argumento(s) requerido(s)" #: py/argcheck.c:122 msgid "extra positional arguments given" -msgstr "" +msgstr "argumentos extra posicionais passados" #: py/argcheck.c:130 msgid "extra keyword arguments given" -msgstr "" +msgstr "argumentos extras de palavras-chave passados" #: py/argcheck.c:142 msgid "argument num/types mismatch" -- cgit v1.2.3 From 14f52c52cb672d1806d5674881bcea0bf3526eff Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 2 Oct 2018 22:34:47 -0500 Subject: Translate strings in nrf directory --- locale/es.po | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/locale/es.po b/locale/es.po index 87edf4ac4..b41c0998f 100644 --- a/locale/es.po +++ b/locale/es.po @@ -705,7 +705,7 @@ msgstr "parámetro config desconocido" #: ports/nrf/common-hal/analogio/AnalogOut.c:37 msgid "AnalogOut functionality not supported" -msgstr "" +msgstr "Funcionalidad AnalogOut sin soporte" #: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" @@ -715,119 +715,123 @@ msgstr "Todos los timers están siendo utilizados" msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" +#: ports/nrf/common-hal/busio/SPI.c:170 +msgid "Baud rate too high for this SPI peripheral" +msgstr "Baud rate demasiado alto para este periférico SPI" + #: ports/nrf/common-hal/busio/UART.c:43 ports/nrf/common-hal/busio/UART.c:47 #: ports/nrf/common-hal/busio/UART.c:51 ports/nrf/common-hal/busio/UART.c:60 #: ports/nrf/common-hal/busio/UART.c:66 ports/nrf/common-hal/busio/UART.c:71 #: ports/nrf/common-hal/busio/UART.c:76 ports/nrf/common-hal/busio/UART.c:81 #: ports/nrf/common-hal/busio/UART.c:86 ports/nrf/common-hal/busio/UART.c:90 msgid "busio.UART not yet implemented" -msgstr "" +msgstr "busio.UART aún sin implementación" #: ports/nrf/common-hal/microcontroller/Processor.c:49 #, c-format msgid "Can not get temperature. status: 0x%02x" -msgstr "" +msgstr "No se puede obtener la temperatura. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." -msgstr "" +msgstr "No se pueden aplicar los parámetros GAP." #: ports/nrf/drivers/bluetooth/ble_drv.c:213 msgid "Cannot set PPCP parameters." -msgstr "" +msgstr "No se pueden establecer los parámetros PPCP." #: ports/nrf/drivers/bluetooth/ble_drv.c:245 msgid "Can not query for the device address." -msgstr "" +msgstr "No se puede consultar la dirección del dispositivo." #: ports/nrf/drivers/bluetooth/ble_drv.c:264 msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "" +msgstr "No se puede agregar el UUID de 128-bits Especifico del Vendedor." #: ports/nrf/drivers/bluetooth/ble_drv.c:284 #: ports/nrf/drivers/bluetooth/ble_drv.c:298 msgid "Can not add Service." -msgstr "" +msgstr "No se puede agregar el Servicio" #: ports/nrf/drivers/bluetooth/ble_drv.c:373 msgid "Can not add Characteristic." -msgstr "" +msgstr "No se puede agregar la Caracteristica" #: ports/nrf/drivers/bluetooth/ble_drv.c:400 msgid "Can not apply device name in the stack." -msgstr "" +msgstr "No se puede aplicar el nombre del dispositivo en el stack." #: ports/nrf/drivers/bluetooth/ble_drv.c:464 #: ports/nrf/drivers/bluetooth/ble_drv.c:514 msgid "Can not encode UUID, to check length." -msgstr "" +msgstr "No se puede codificar el UUID, para revisar la longitud." #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 msgid "Can encode UUID into the advertisement packet." -msgstr "" +msgstr "Se puede codificar el UUID en el paquete de anuncio." #: ports/nrf/drivers/bluetooth/ble_drv.c:545 msgid "Can not fit data into the advertisement packet." -msgstr "" +msgstr "Los datos no caben en el paquete de anuncio." #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "" +msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format msgid "Can not start advertisement. status: 0x%02x" -msgstr "" +msgstr "No se puede inicar el anuncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format msgid "Can not stop advertisement. status: 0x%02x" -msgstr "" +msgstr "No se puede detener el anuncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 #: ports/nrf/drivers/bluetooth/ble_drv.c:726 #, c-format msgid "Can not read attribute value. status: 0x%02x" -msgstr "" +msgstr "No se puede leer el valor del atributo. status 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:667 #: ports/nrf/drivers/bluetooth/ble_drv.c:756 #, c-format msgid "Can not write attribute value. status: 0x%02x" -msgstr "" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:691 #, c-format msgid "Can not notify attribute value. status: 0x%02x" -msgstr "" +msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:784 #, c-format msgid "Can not start scanning. status: 0x%02x" -msgstr "" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:829 #, c-format msgid "Can not connect. status: 0x%02x" -msgstr "" +msgstr "No se puede conectar. status: 0x%02x" #: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 #: ports/nrf/modules/ubluepy/ubluepy_service.c:80 #: ports/nrf/modules/ubluepy/ubluepy_service.c:132 #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 msgid "Invalid UUID parameter" -msgstr "" +msgstr "Parámetro UUID inválido" #: ports/nrf/modules/ubluepy/ubluepy_service.c:73 msgid "Invalid Service type" -msgstr "" +msgstr "Tipo de servicio inválido" #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 msgid "Invalid UUID string length" -msgstr "" +msgstr "Longitud de string UUID inválida" #: ports/unix/modffi.c:138 msgid "Unknown type" -- cgit v1.2.3 From 22f6869bdf794b4a9d20aa10f0d38c3c8502f874 Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 3 Oct 2018 21:07:16 -0500 Subject: Address suggestions @carlosperate --- locale/es.po | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/locale/es.po b/locale/es.po index b41c0998f..1a3ad747d 100644 --- a/locale/es.po +++ b/locale/es.po @@ -705,7 +705,7 @@ msgstr "parámetro config desconocido" #: ports/nrf/common-hal/analogio/AnalogOut.c:37 msgid "AnalogOut functionality not supported" -msgstr "Funcionalidad AnalogOut sin soporte" +msgstr "Funcionalidad AnalogOut no soportada" #: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" @@ -755,7 +755,7 @@ msgstr "No se puede agregar el Servicio" #: ports/nrf/drivers/bluetooth/ble_drv.c:373 msgid "Can not add Characteristic." -msgstr "No se puede agregar la Caracteristica" +msgstr "No se puede agregar la Característica" #: ports/nrf/drivers/bluetooth/ble_drv.c:400 msgid "Can not apply device name in the stack." @@ -827,7 +827,7 @@ msgstr "Parámetro UUID inválido" #: ports/nrf/modules/ubluepy/ubluepy_service.c:73 msgid "Invalid Service type" -msgstr "Tipo de servicio inválido" +msgstr "Tipo de Servicio inválido" #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 msgid "Invalid UUID string length" @@ -1621,7 +1621,7 @@ msgstr "struct: index fuera de rango" #: py/objstr.c:1071 #, fuzzy msgid "attributes not supported yet" -msgstr "bytes > 8 bits no son soportados" +msgstr "bytes > 8 bits no soportados" #: py/objstr.c:1079 msgid "" @@ -1803,7 +1803,6 @@ msgid "int() arg 2 must be >= 2 and <= 36" msgstr "" #: py/parsenum.c:151 -#, fuzzy msgid "invalid syntax for integer" msgstr "formato inválido" @@ -1813,12 +1812,10 @@ msgid "invalid syntax for integer with base %d" msgstr "" #: py/parsenum.c:339 -#, fuzzy msgid "invalid syntax for number" msgstr "argumentos inválidos" #: py/parsenum.c:342 -#, fuzzy msgid "decimal numbers not supported" msgstr "bytes > 8 bits no son soportados" @@ -1833,7 +1830,6 @@ msgid "can only save bytecode" msgstr "" #: py/runtime.c:206 -#, fuzzy msgid "name not defined" msgstr "módulo no encontrado" -- cgit v1.2.3 From 21ddb6b9b9c0b7400c914e19a9b873d362c9e100 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Oct 2018 21:37:16 +0700 Subject: fix tinyusb cdc issue --- lib/tinyusb | 2 +- ports/nrf/nrfx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index a660fb0cf..33c61bfda 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit a660fb0cfc8641d5645d1cdea76027266b278388 +Subproject commit 33c61bfda2c3aada3cb06d36e12d7cf57da02037 diff --git a/ports/nrf/nrfx b/ports/nrf/nrfx index 67710e47c..d4ebe15f5 160000 --- a/ports/nrf/nrfx +++ b/ports/nrf/nrfx @@ -1 +1 @@ -Subproject commit 67710e47c7313cc56a15748e485079831ee6a3af +Subproject commit d4ebe15f58de1442e3eed93b40d13930e7785903 -- cgit v1.2.3 From 76008ce304e09394733a10d56b944218b41630ca Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 2 Oct 2018 18:06:52 -0700 Subject: Introduce audioio.Mixer which can mix multiple audio samples to produce a single sample. Only works with 16 bit samples on the M4. Fixes #987 --- ports/atmel-samd/Makefile | 2 + ports/atmel-samd/audio_dma.c | 76 --------- shared-bindings/audioio/Mixer.c | 249 +++++++++++++++++++++++++++ shared-bindings/audioio/Mixer.h | 52 ++++++ shared-bindings/audioio/__init__.c | 4 + shared-module/audioio/Mixer.c | 338 +++++++++++++++++++++++++++++++++++++ shared-module/audioio/Mixer.h | 75 ++++++++ shared-module/audioio/WaveFile.c | 18 +- shared-module/audioio/__init__.c | 125 ++++++++++++++ shared-module/audioio/__init__.h | 17 ++ shared-module/displayio/Sprite.c | 2 +- 11 files changed, 880 insertions(+), 78 deletions(-) create mode 100644 shared-bindings/audioio/Mixer.c create mode 100644 shared-bindings/audioio/Mixer.h create mode 100644 shared-module/audioio/Mixer.c create mode 100644 shared-module/audioio/Mixer.h create mode 100644 shared-module/audioio/__init__.c diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index f8e5051c2..c8ade987d 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -407,6 +407,8 @@ ifneq ($(CHIP_VARIANT),SAMR21G18A) audioio/__init__.c \ audioio/AudioOut.c SRC_SHARED_MODULE += \ + audioio/__init__.c \ + audioio/Mixer.c \ audioio/RawSample.c \ audioio/WaveFile.c endif diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 45d698c17..68d6f182d 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -40,82 +40,6 @@ static audio_dma_t* audio_dma_state[AUDIO_DMA_CHANNEL_COUNT]; // This cannot be in audio_dma_state because it's volatile. static volatile bool audio_dma_pending[AUDIO_DMA_CHANNEL_COUNT]; -uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - return sample->sample_rate; - } - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - return file->sample_rate; - } - return 16000; -} - -uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - return sample->bits_per_sample; - } - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - return file->bits_per_sample; - } - return 8; -} - -uint8_t audiosample_channel_count(mp_obj_t sample_obj) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - return sample->channel_count; - } - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - return file->channel_count; - } - return 1; -} - -static void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - audioio_rawsample_reset_buffer(sample, single_channel, audio_channel); - } - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - audioio_wavefile_reset_buffer(file, single_channel, audio_channel); - } -} - -static audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, - bool single_channel, - uint8_t channel, - uint8_t** buffer, uint32_t* buffer_length) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length); - } - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length); - } - return GET_BUFFER_DONE; -} - -static void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, - bool* single_buffer, bool* samples_signed, - uint32_t* max_buffer_length, uint8_t* spacing) { - if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { - audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); - audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer, - samples_signed, max_buffer_length, spacing); - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { - audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed, - max_buffer_length, spacing); - } -} - uint8_t find_free_audio_dma_channel(void) { uint8_t channel; for (channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audioio/Mixer.c new file mode 100644 index 000000000..fece3b000 --- /dev/null +++ b/shared-bindings/audioio/Mixer.c @@ -0,0 +1,249 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audioio/Mixer.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audioio +//| +//| :class:`Mixer` -- Mixes one or more audio samples together +//| =========================================================== +//| +//| Mixer mixes multiple samples into one sample. +//| +//| .. class:: Mixer(channel_count=2, buffer_size=1024) +//| +//| Create a Mixer object that can mix multiple channels with the same sample rate. +//| +//| :param int channel_count: The maximum number of samples to mix at once +//| :param int buffer_size: The total size in bytes of the buffers to mix into +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audioio +//| import digitalio +//| +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| music = audioio.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) +//| drum = audioio.WaveFile(open("drum.wav", "rb")) +//| mixer = audioio.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(mixer) +//| mixer.play(music, voice=0) +//| while mixer.playing: +//| mixer.play(drum, voice=1) +//| time.sleep(1) +//| print("stopped") +//| +STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 2, true); + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1024} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + }; + 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_int_t voice_count = args[ARG_voice_count].u_int; + if (voice_count < 1 || voice_count > 255) { + mp_raise_ValueError(translate("Invalid voice count")); + } + + mp_int_t channel_count = args[ARG_channel_count].u_int; + if (channel_count < 1 || channel_count > 2) { + mp_raise_ValueError(translate("Invalid channel count")); + } + mp_int_t sample_rate = args[ARG_sample_rate].u_int; + if (sample_rate < 1) { + mp_raise_ValueError(translate("Sample rate must be positive")); + } + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(translate("bits_per_sample must be 8 or 16")); + } + audioio_mixer_obj_t *self = m_new_obj_var(audioio_mixer_obj_t, audioio_mixer_voice_t, voice_count); + self->base.type = &audioio_mixer_type; + common_hal_audioio_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the Mixer and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioio_mixer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audioio_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audioio_mixer_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, audioio_mixer_obj___exit__); + + +//| .. method:: play(sample, *, voice=0, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`. +//| +//| If other samples are already playing, the encodings must match. +//| +STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_voice, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audioio_mixer_play(self, sample, args[ARG_voice].u_int, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_play_obj, 1, audioio_mixer_obj_play); + +//| .. method:: stop(voice=0) +//| +//| Stops playback and resets to the start of the sample on the given channel. +//| +STATIC mp_obj_t audioio_mixer_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_voice }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + }; + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_audioio_mixer_stop(self, args[ARG_voice].u_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_obj, 1, audioio_mixer_obj_stop); + +//| .. attribute:: playing +//| +//| True when an audio sample is being output even if `paused`. (read-only) +//| +STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing); + +const mp_obj_property_t audioio_mixer_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_mixer_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: sample_rate +//| +//| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second). +//| +STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate); + + +const mp_obj_property_t audioio_mixer_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_mixer_get_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audioio_mixer_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_mixer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_mixer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_mixer_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audioio_mixer_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audioio_mixer_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_mixer_sample_rate_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audioio_mixer_locals_dict, audioio_mixer_locals_dict_table); + +const mp_obj_type_t audioio_mixer_type = { + { &mp_type_type }, + .name = MP_QSTR_Mixer, + .make_new = audioio_mixer_make_new, + .locals_dict = (mp_obj_dict_t*)&audioio_mixer_locals_dict, +}; diff --git a/shared-bindings/audioio/Mixer.h b/shared-bindings/audioio/Mixer.h new file mode 100644 index 000000000..ad1a9fe05 --- /dev/null +++ b/shared-bindings/audioio/Mixer.h @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/audioio/Mixer.h" +#include "shared-bindings/audioio/RawSample.h" + +extern const mp_obj_type_t audioio_mixer_type; + +void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate); + +void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self); +bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self); +void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t voice, bool loop); +void common_hal_audioio_mixer_stop(audioio_mixer_obj_t* self, uint8_t voice); + +bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self); +uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index 8a00b43d8..4786b6425 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -32,6 +32,8 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audioio/__init__.h" #include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/audioio/Mixer.h" +#include "shared-bindings/audioio/RawSample.h" #include "shared-bindings/audioio/WaveFile.h" //| :mod:`audioio` --- Support for audio input and output @@ -49,6 +51,7 @@ //| :maxdepth: 3 //| //| AudioOut +//| Mixer //| RawSample //| WaveFile //| @@ -61,6 +64,7 @@ STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, { MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) }, + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, }; diff --git a/shared-module/audioio/Mixer.c b/shared-module/audioio/Mixer.c new file mode 100644 index 000000000..85acbf0ab --- /dev/null +++ b/shared-module/audioio/Mixer.c @@ -0,0 +1,338 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audioio/Mixer.h" + +#include + +#include "py/runtime.h" +#include "shared-module/audioio/__init__.h" +#include "shared-module/audioio/RawSample.h" + +void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate) { + self->len = buffer_size / 2 / sizeof(uint32_t) * sizeof(uint32_t); + + self->first_buffer = m_malloc(self->len, false); + if (self->first_buffer == NULL) { + common_hal_audioio_mixer_deinit(self); + mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer")); + } + + self->second_buffer = m_malloc(self->len, false); + if (self->second_buffer == NULL) { + common_hal_audioio_mixer_deinit(self); + mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer")); + } + + self->bits_per_sample = bits_per_sample; + self->samples_signed = samples_signed; + self->channel_count = channel_count; + self->sample_rate = sample_rate; + self->voice_count = voice_count; + + for (uint8_t i = 0; i < self->voice_count; i++) { + self->voice[i].sample = NULL; + } +} + +void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self) { + self->first_buffer = NULL; + self->second_buffer = NULL; +} + +bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self) { + return self->first_buffer == NULL; +} + +uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self) { + return self->sample_rate; +} + +void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t v, bool loop) { + if (v >= self->voice_count) { + mp_raise_ValueError(translate("Voice index too high")); + } + if (audiosample_sample_rate(sample) != self->sample_rate) { + mp_raise_ValueError(translate("The sample's sample rate does not match the mixer's")); + } + if (audiosample_channel_count(sample) != self->channel_count) { + mp_raise_ValueError(translate("The sample's channel count does not match the mixer's")); + } + if (audiosample_bits_per_sample(sample) != self->bits_per_sample) { + mp_raise_ValueError(translate("The sample's bits_per_sample does not match the mixer's")); + } + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, + &max_buffer_length, &spacing); + if (samples_signed != self->samples_signed) { + mp_raise_ValueError(translate("The sample's signedness does not match the mixer's")); + } + audioio_mixer_voice_t* voice = &self->voice[v]; + voice->sample = sample; + voice->loop = loop; + + audiosample_reset_buffer(sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); + // Track length in terms of words. + voice->buffer_length /= sizeof(uint32_t); + voice->more_data = result == GET_BUFFER_MORE_DATA; +} + +void common_hal_audioio_mixer_stop(audioio_mixer_obj_t* self, uint8_t voice) { + self->voice[voice].sample = NULL; +} + +bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self) { + for (int32_t v = 0; v < self->voice_count; v++) { + if (self->voice[v].sample != NULL) { + return true; + } + } + return false; +} + +void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel) { + for (int32_t i = 0; i < self->voice_count; i++) { + self->voice[i].sample = NULL; + } +} + +uint32_t add8signed(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + return __QADD8(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 4; i++) { + int8_t ai = a >> (sizeof(int8_t) * i); + int8_t bi = b >> (sizeof(int8_t) * i); + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > CHAR_MAX) { + intermediate = CHAR_MAX; + } else if (intermediate < CHAR_MIN) { + intermediate = CHAR_MIN; + } + result |= ((int8_t) intermediate) >> (sizeof(int8_t) * i); + } + return result; + #endif +} + +uint32_t add8unsigned(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + // Subtract out the DC offset, add and then shift back. + a = __USUB8(a, 0x80808080); + b = __USUB8(b, 0x80808080); + uint32_t sum = __QADD8(a, b); + return __UADD8(sum, 0x80808080); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 4; i++) { + uint8_t ai = a >> (sizeof(uint8_t) * i); + uint8_t bi = b >> (sizeof(uint8_t) * i); + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > UCHAR_MAX) { + intermediate = UCHAR_MAX; + } + result |= ((uint8_t) intermediate) >> (sizeof(uint8_t) * i); + } + return result; + #endif +} + +uint32_t add16signed(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + return __QADD16(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + int16_t ai = a >> (sizeof(int16_t) * i); + int16_t bi = b >> (sizeof(int16_t) * i); + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= ((int16_t) intermediate) >> (sizeof(int16_t) * i); + } + return result; + #endif +} + +uint32_t add16unsigned(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + // Subtract out the DC offset, add and then shift back. + a = __USUB16(a, 0x80008000); + b = __USUB16(b, 0x80008000); + uint32_t sum = __QADD16(a, b); + return __UADD16(sum, 0x80008000); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + uint16_t ai = a >> (sizeof(uint16_t) * i); + uint16_t bi = b >> (sizeof(uint16_t) * i); + uint32_t intermediate = (uint32_t) ai + bi; + if (intermediate > USHRT_MAX) { + intermediate = USHRT_MAX; + } + result |= ((uint16_t) intermediate) >> (sizeof(int16_t) * i); + } + return result; + #endif +} + +audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { + if (!single_channel) { + channel = 0; + } + + uint32_t channel_read_count = self->left_read_count; + if (channel == 1) { + channel_read_count = self->right_read_count; + } + *buffer_length = self->len; + + bool need_more_data = self->read_count == channel_read_count; + if (need_more_data) { + uint32_t* word_buffer; + if (self->use_first_buffer) { + *buffer = (uint8_t*) self->first_buffer; + word_buffer = self->first_buffer; + } else { + *buffer = (uint8_t*) self->second_buffer; + word_buffer = self->second_buffer; + } + self->use_first_buffer = !self->use_first_buffer; + bool voices_active = false; + for (int32_t v = 0; v < self->voice_count; v++) { + audioio_mixer_voice_t* voice = &self->voice[v]; + if (voice->sample == NULL) { + continue; + } + + uint32_t j = 0; + for (uint32_t i = 0; i < self->len / sizeof(uint32_t); i++) { + if (j >= voice->buffer_length) { + if (!voice->more_data) { + if (voice->loop) { + audiosample_reset_buffer(voice->sample, false, 0); + } else { + voice->sample = NULL; + break; + } + } + // Load another buffer + audioio_get_buffer_result_t result = audiosample_get_buffer(voice->sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); + // Track length in terms of words. + voice->buffer_length /= sizeof(uint32_t); + voice->more_data = result == GET_BUFFER_MORE_DATA; + j = 0; + } + // First active voice gets copied over verbatim. + uint32_t sample_value = voice->remaining_buffer[j]; + if (!voices_active) { + word_buffer[i] = sample_value; + } else { + if (self->bits_per_sample == 8) { + if (self->samples_signed) { + word_buffer[i] = add8signed(word_buffer[i], sample_value); + } else { + word_buffer[i] = add8unsigned(word_buffer[i], sample_value); + } + } else { + if (self->samples_signed) { + word_buffer[i] = add16signed(word_buffer[i], sample_value); + } else { + word_buffer[i] = add16unsigned(word_buffer[i], sample_value); + } + } + } + j++; + } + voice->buffer_length -= j; + voice->remaining_buffer += j; + + voices_active = true; + } + + // No voice is active so zero out the signal. + if (!voices_active) { + uint32_t zero = 0; + if (!self->samples_signed) { + if (self->bits_per_sample == 8) { + zero = 0x7f7f7f7f; + } else { + zero = 0x7fff7fff; + } + } + for (uint32_t i = 0; i < self->len / sizeof(uint32_t); i++) { + word_buffer[i] = zero; + } + } + self->read_count += 1; + } else if (!self->use_first_buffer) { + *buffer = (uint8_t*) self->first_buffer; + } else { + *buffer = (uint8_t*) self->second_buffer; + } + + + if (channel == 0) { + self->left_read_count += 1; + } else if (channel == 1) { + self->right_read_count += 1; + *buffer = *buffer + self->bits_per_sample / 8; + } + return GET_BUFFER_MORE_DATA; +} + +void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + *single_buffer = false; + *samples_signed = self->samples_signed; + *max_buffer_length = self->len; + if (single_channel) { + *spacing = self->channel_count; + } else { + *spacing = 1; + } +} diff --git a/shared-module/audioio/Mixer.h b/shared-module/audioio/Mixer.h new file mode 100644 index 000000000..6a88fe0bd --- /dev/null +++ b/shared-module/audioio/Mixer.h @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H + +#include "py/obj.h" + +#include "shared-module/audioio/__init__.h" + +typedef struct { + mp_obj_t sample; + bool loop; + bool more_data; + uint32_t* remaining_buffer; + uint32_t buffer_length; +} audioio_mixer_voice_t; + +typedef struct { + mp_obj_base_t base; + uint32_t* first_buffer; + uint32_t* second_buffer; + uint32_t len; // in words + uint8_t bits_per_sample; + bool use_first_buffer; + bool samples_signed; + uint8_t channel_count; + uint32_t sample_rate; + + uint32_t read_count; + uint32_t left_read_count; + uint32_t right_read_count; + + uint8_t voice_count; + audioio_mixer_voice_t voice[]; +} audioio_mixer_obj_t; + + +// These are not available from Python because it may be called in an interrupt. +void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel); +audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length); // length in bytes +void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H diff --git a/shared-module/audioio/WaveFile.c b/shared-module/audioio/WaveFile.c index 7efad05e0..e5a7b1a3b 100644 --- a/shared-module/audioio/WaveFile.c +++ b/shared-module/audioio/WaveFile.c @@ -200,13 +200,29 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t* if (f_read(&self->file->fp, *buffer, num_bytes_to_load, &length_read) != FR_OK) { return GET_BUFFER_ERROR; } + self->bytes_remaining -= length_read; + // Pad the last buffer to word align it. + if (self->bytes_remaining == 0 && length_read % sizeof(uint32_t) != 0) { + uint32_t pad = length_read % sizeof(uint32_t); + length_read += pad; + if (self->bits_per_sample == 8) { + for (uint32_t i = 0; i < pad; i++) { + ((uint8_t*) (*buffer))[length_read / sizeof(uint8_t) - i - 1] = 0x80; + } + } else if (self->bits_per_sample == 16) { + // We know the buffer is aligned because we allocated it onto the heap ourselves. + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + ((int16_t*) (*buffer))[length_read / sizeof(int16_t) - 1] = 0; + #pragma GCC diagnostic pop + } + } *buffer_length = length_read; if (self->buffer_index % 2 == 1) { self->second_buffer_length = length_read; } else { self->buffer_length = length_read; } - self->bytes_remaining -= length_read; self->buffer_index += 1; self->read_count += 1; } diff --git a/shared-module/audioio/__init__.c b/shared-module/audioio/__init__.c new file mode 100644 index 000000000..b87b06a83 --- /dev/null +++ b/shared-module/audioio/__init__.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/audioio/__init__.h" + +#include "py/obj.h" +#include "shared-bindings/audioio/Mixer.h" +#include "shared-bindings/audioio/RawSample.h" +#include "shared-bindings/audioio/WaveFile.h" +#include "shared-module/audioio/Mixer.h" +#include "shared-module/audioio/RawSample.h" +#include "shared-module/audioio/WaveFile.h" + +uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->sample_rate; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->sample_rate; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->sample_rate; + } + return 16000; +} + +uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->bits_per_sample; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->bits_per_sample; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->bits_per_sample; + } + return 8; +} + +uint8_t audiosample_channel_count(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->channel_count; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->channel_count; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->channel_count; + } + return 1; +} + +void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + audioio_rawsample_reset_buffer(sample, single_channel, audio_channel); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_wavefile_reset_buffer(file, single_channel, audio_channel); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_mixer_reset_buffer(file, single_channel, audio_channel); + } +} + +audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, + bool single_channel, + uint8_t channel, + uint8_t** buffer, uint32_t* buffer_length) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audioio_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length); + } + return GET_BUFFER_DONE; +} + +void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer, + samples_signed, max_buffer_length, spacing); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + max_buffer_length, spacing); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + max_buffer_length, spacing); + } +} diff --git a/shared-module/audioio/__init__.h b/shared-module/audioio/__init__.h index 2491beb12..c805f3116 100644 --- a/shared-module/audioio/__init__.h +++ b/shared-module/audioio/__init__.h @@ -27,10 +27,27 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H #define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H +#include +#include + +#include "py/obj.h" + typedef enum { GET_BUFFER_DONE, // No more data to read GET_BUFFER_MORE_DATA, // More data to read. GET_BUFFER_ERROR, // Error while reading data. } audioio_get_buffer_result_t; +uint32_t audiosample_sample_rate(mp_obj_t sample_obj); +uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj); +uint8_t audiosample_channel_count(mp_obj_t sample_obj); +void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel); +audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, + bool single_channel, + uint8_t channel, + uint8_t** buffer, uint32_t* buffer_length); +void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + #endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H diff --git a/shared-module/displayio/Sprite.c b/shared-module/displayio/Sprite.c index 4fe8d1ff6..87600f721 100644 --- a/shared-module/displayio/Sprite.c +++ b/shared-module/displayio/Sprite.c @@ -68,7 +68,7 @@ bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y, if (y < 0 || y >= self->height || x >= self->width || x < 0) { return false; } - uint32_t value; + uint32_t value = 0; if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { value = common_hal_displayio_bitmap_get_pixel(self->bitmap, x, y); } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { -- cgit v1.2.3 From 623f8d3b8c14fd924e31b2b1b044b513c0b1ee3c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 12:00:05 -0700 Subject: Don't freeze the tests directory --- tools/preprocess_frozen_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py index d157deeee..bb6959f0d 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -33,7 +33,7 @@ def copy_and_process(in_dir, out_dir): for root, subdirs, files in os.walk(in_dir): # Skip library examples directories. - if Path(root).name in ['examples', 'docs']: + if Path(root).name in ['examples', 'docs', 'tests']: continue for file in files: -- cgit v1.2.3 From 2ec7f98c905c5b2e758be075897329eee704dcfe Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 12:01:36 -0700 Subject: Update translations --- locale/circuitpython.pot | 60 ++++++++++++++++++++++++++++++---------- locale/de_DE.po | 63 ++++++++++++++++++++++++++++++++---------- locale/en_US.po | 60 ++++++++++++++++++++++++++++++---------- locale/es.po | 64 +++++++++++++++++++++++++++++++++---------- locale/fil.po | 65 ++++++++++++++++++++++++++++++++++---------- locale/fr.po | 64 +++++++++++++++++++++++++++++++++---------- locale/pt_BR.po | 71 ++++++++++++++++++++++++++++++++++++------------ 7 files changed, 344 insertions(+), 103 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 232ad7c46..d57c06a29 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:18-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -218,7 +218,7 @@ msgstr "" msgid "soft reboot\n" msgstr "" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1983,6 +1979,22 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +#: shared-bindings/audioio/Mixer.c:94 +msgid "Invalid voice count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:99 +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +msgid "bits_per_sample must be 8 or 16" +msgstr "" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2273,6 +2285,34 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "" @@ -2293,14 +2333,6 @@ msgstr "" msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 790b23442..cad68745b 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:17-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -227,7 +227,7 @@ msgstr "" msgid "soft reboot\n" msgstr "weicher reboot\n" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "Alle sync event Kanäle werden benutzt" @@ -713,10 +713,6 @@ msgstr "Alle timer werden benutzt" msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1996,6 +1992,25 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "Ungültiger clock pin" + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "Ungültiger clock pin" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits müssen 8 sein" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2287,6 +2302,34 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "" @@ -2307,14 +2350,6 @@ msgstr "" msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index 6e576f150..fb247f94d 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:17-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -218,7 +218,7 @@ msgstr "" msgid "soft reboot\n" msgstr "" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1983,6 +1979,22 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +#: shared-bindings/audioio/Mixer.c:94 +msgid "Invalid voice count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:99 +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +msgid "bits_per_sample must be 8 or 16" +msgstr "" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2273,6 +2285,34 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "" @@ -2293,14 +2333,6 @@ msgstr "" msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "" diff --git a/locale/es.po b/locale/es.po index 2ac904943..c75724ce0 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:17-0700\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -233,7 +233,7 @@ msgstr "" msgid "soft reboot\n" msgstr "reinicio suave\n" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "Todos los sync event channels están siendo utilizados" @@ -719,10 +719,6 @@ msgstr "Todos los timers están siendo utilizados" msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2029,6 +2025,26 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "Dirección inválida." + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "argumentos inválidos" + +#: shared-bindings/audioio/Mixer.c:103 +#, fuzzy +msgid "Sample rate must be positive" +msgstr "STA debe estar activo" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits debe ser 8" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2321,6 +2337,34 @@ msgid "" "Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "" @@ -2341,14 +2385,6 @@ msgstr "" msgid "Invalid file" msgstr "" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index 7c8c4fdfe..5c274a6f8 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:17-0700\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -230,7 +230,7 @@ msgstr "" msgid "soft reboot\n" msgstr "malambot na reboot\n" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "Lahat ng sync event channels ay ginagamit" @@ -719,10 +719,6 @@ msgstr "Lahat ng timer ginagamit" msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -743,7 +739,6 @@ msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 #: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 #: ports/nrf/common-hal/busio/UART.c:364 -#, fuzzy msgid "busio.UART not available" msgstr "" @@ -2024,6 +2019,26 @@ msgstr "" "ang destination buffer ay dapat na isang bytearray o array ng uri na 'B' " "para sa bit_depth = 8" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "Mali ang tipo ng serbisyo" + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "Maling argumento" + +#: shared-bindings/audioio/Mixer.c:103 +#, fuzzy +msgid "Sample rate must be positive" +msgstr "Dapat aktibo ang STA" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits ay dapat 7, 8 o 9" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2333,6 +2348,34 @@ msgstr "" "Object ay deinitialized at hindi na magagamit. Lumikha ng isang bagong " "Object." +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "Hindi ma-iallocate ang first buffer" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "Hindi ma-iallocate ang second buffer" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "May hindi tama sa wave file" @@ -2353,14 +2396,6 @@ msgstr "Dapat sunurin ng Data chunk ang fmt chunk" msgid "Invalid file" msgstr "Mali ang file" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "Hindi ma-iallocate ang first buffer" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "Hindi ma-iallocate ang second buffer" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "Masyadong mahaba ang Clock stretch" diff --git a/locale/fr.po b/locale/fr.po index 04d7a0665..4bf0037ed 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:18-0700\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -225,7 +225,7 @@ msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." msgid "soft reboot\n" msgstr "redémarrage logiciel\n" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "Tous les canaux d'événements de synchro sont utilisés" @@ -715,10 +715,6 @@ msgstr "Tous les timers sont utilisés" msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2015,6 +2011,26 @@ msgid "" msgstr "" "le tampon de destination doit être un tableau de type 'B' pour bit_depth = 8" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "Type de service invalide" + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "Argument invalide" + +#: shared-bindings/audioio/Mixer.c:103 +#, fuzzy +msgid "Sample rate must be positive" +msgstr "'STA' doit être actif" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits doivent être 7, 8 ou 9" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2329,6 +2345,34 @@ msgstr "" "L'objet a été désinitialisé et ne peut plus être utilisé. Créez un nouvel " "objet." +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "Impossible d'allouer le 1er tampon" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "Impossible d'allouer le 2e tampon" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "Fichier WAVE invalide" @@ -2349,14 +2393,6 @@ msgstr "Un bloc de données doit suivre un bloc de format" msgid "Invalid file" msgstr "Fichier invalide" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "Impossible d'allouer le 1er tampon" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "Impossible d'allouer le 2e tampon" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "Période de l'horloge trop longue" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index d6b283c9f..c71bb66a0 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-05 15:18-0700\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -218,7 +218,7 @@ msgstr "" msgid "soft reboot\n" msgstr "" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1985,6 +1981,25 @@ msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "certificado inválido" + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "certificado inválido" + +#: shared-bindings/audioio/Mixer.c:103 +msgid "Sample rate must be positive" +msgstr "" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits devem ser 8" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2009,19 +2024,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "Fase Inválida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "Número inválido de bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" @@ -2276,6 +2291,34 @@ msgid "" msgstr "" "Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "Não pôde alocar primeiro buffer" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "Não pôde alocar segundo buffer" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "Aqruivo de ondas inválido" @@ -2296,14 +2339,6 @@ msgstr "Pedaço de dados deve seguir o pedaço de cortes" msgid "Invalid file" msgstr "Arquivo inválido" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "Não pôde alocar primeiro buffer" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "Não pôde alocar segundo buffer" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "Clock se estendeu por tempo demais" -- cgit v1.2.3 From 8587d8edf0a794644783e26ac243d1ba141a85ca Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 13:00:22 -0700 Subject: Fix voice ending in the middle of a buffer. --- shared-module/audioio/Mixer.c | 55 +++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/shared-module/audioio/Mixer.c b/shared-module/audioio/Mixer.c index 85acbf0ab..c669402bd 100644 --- a/shared-module/audioio/Mixer.c +++ b/shared-module/audioio/Mixer.c @@ -244,30 +244,47 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, bool voices_active = false; for (int32_t v = 0; v < self->voice_count; v++) { audioio_mixer_voice_t* voice = &self->voice[v]; - if (voice->sample == NULL) { - continue; - } uint32_t j = 0; + bool voice_done = voice->sample == NULL; for (uint32_t i = 0; i < self->len / sizeof(uint32_t); i++) { - if (j >= voice->buffer_length) { + if (!voice_done && j >= voice->buffer_length) { if (!voice->more_data) { if (voice->loop) { audiosample_reset_buffer(voice->sample, false, 0); } else { voice->sample = NULL; - break; + voice_done = true; } } - // Load another buffer - audioio_get_buffer_result_t result = audiosample_get_buffer(voice->sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); - // Track length in terms of words. - voice->buffer_length /= sizeof(uint32_t); - voice->more_data = result == GET_BUFFER_MORE_DATA; - j = 0; + if (!voice_done) { + // Load another buffer + audioio_get_buffer_result_t result = audiosample_get_buffer(voice->sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); + // Track length in terms of words. + voice->buffer_length /= sizeof(uint32_t); + voice->more_data = result == GET_BUFFER_MORE_DATA; + j = 0; + } } // First active voice gets copied over verbatim. - uint32_t sample_value = voice->remaining_buffer[j]; + uint32_t sample_value; + if (voice_done) { + // Exit early if another voice already set all samples once. + if (voices_active) { + continue; + } + sample_value = 0; + if (!self->samples_signed) { + if (self->bits_per_sample == 8) { + sample_value = 0x7f7f7f7f; + } else { + sample_value = 0x7fff7fff; + } + } + } else { + sample_value = voice->remaining_buffer[j]; + } + if (!voices_active) { word_buffer[i] = sample_value; } else { @@ -293,20 +310,6 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, voices_active = true; } - // No voice is active so zero out the signal. - if (!voices_active) { - uint32_t zero = 0; - if (!self->samples_signed) { - if (self->bits_per_sample == 8) { - zero = 0x7f7f7f7f; - } else { - zero = 0x7fff7fff; - } - } - for (uint32_t i = 0; i < self->len / sizeof(uint32_t); i++) { - word_buffer[i] = zero; - } - } self->read_count += 1; } else if (!self->use_first_buffer) { *buffer = (uint8_t*) self->first_buffer; -- cgit v1.2.3 From 15d80a8c46e26a2ac806b52e75f584bd96fa683f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 13:03:28 -0700 Subject: Fix doc build --- shared-bindings/audioio/Mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audioio/Mixer.c index fece3b000..d353daa78 100644 --- a/shared-bindings/audioio/Mixer.c +++ b/shared-bindings/audioio/Mixer.c @@ -192,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_obj, 1, audioio_mixer_obj_stop); //| .. attribute:: playing //| -//| True when an audio sample is being output even if `paused`. (read-only) +//| True when any voice is being output. (read-only) //| STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) { audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); -- cgit v1.2.3 From 3c6812f2c1c900b4b6fd52bc9a5ee3b6f483626f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 14:43:27 -0700 Subject: Fix M0 math --- shared-module/audioio/Mixer.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/shared-module/audioio/Mixer.c b/shared-module/audioio/Mixer.c index c669402bd..0709e2e42 100644 --- a/shared-module/audioio/Mixer.c +++ b/shared-module/audioio/Mixer.c @@ -131,25 +131,28 @@ void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, } } + #pragma GCC push_options + #pragma GCC optimize ("O0") uint32_t add8signed(uint32_t a, uint32_t b) { #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) return __QADD8(a, b); #else uint32_t result = 0; for (int8_t i = 0; i < 4; i++) { - int8_t ai = a >> (sizeof(int8_t) * i); - int8_t bi = b >> (sizeof(int8_t) * i); + int8_t ai = a >> (sizeof(int8_t) * 8 * i); + int8_t bi = b >> (sizeof(int8_t) * 8 * i); int32_t intermediate = (int32_t) ai + bi; if (intermediate > CHAR_MAX) { intermediate = CHAR_MAX; } else if (intermediate < CHAR_MIN) { - intermediate = CHAR_MIN; + //intermediate = CHAR_MIN; } - result |= ((int8_t) intermediate) >> (sizeof(int8_t) * i); + result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int8_t) * 8 * i); } return result; #endif } + #pragma GCC pop_options uint32_t add8unsigned(uint32_t a, uint32_t b) { #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) @@ -161,13 +164,13 @@ uint32_t add8unsigned(uint32_t a, uint32_t b) { #else uint32_t result = 0; for (int8_t i = 0; i < 4; i++) { - uint8_t ai = a >> (sizeof(uint8_t) * i); - uint8_t bi = b >> (sizeof(uint8_t) * i); + int8_t ai = (a >> (sizeof(uint8_t) * 8 * i)) - 128; + int8_t bi = (b >> (sizeof(uint8_t) * 8 * i)) - 128; int32_t intermediate = (int32_t) ai + bi; if (intermediate > UCHAR_MAX) { intermediate = UCHAR_MAX; } - result |= ((uint8_t) intermediate) >> (sizeof(uint8_t) * i); + result |= ((uint8_t) intermediate + 128) << (sizeof(uint8_t) * 8 * i); } return result; #endif @@ -179,15 +182,15 @@ uint32_t add16signed(uint32_t a, uint32_t b) { #else uint32_t result = 0; for (int8_t i = 0; i < 2; i++) { - int16_t ai = a >> (sizeof(int16_t) * i); - int16_t bi = b >> (sizeof(int16_t) * i); + int16_t ai = a >> (sizeof(int16_t) * 8 * i); + int16_t bi = b >> (sizeof(int16_t) * 8 * i); int32_t intermediate = (int32_t) ai + bi; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { intermediate = SHRT_MIN; } - result |= ((int16_t) intermediate) >> (sizeof(int16_t) * i); + result |= (((uint32_t) intermediate) & 0xffff) << (sizeof(int16_t) * 8 * i); } return result; #endif @@ -203,13 +206,13 @@ uint32_t add16unsigned(uint32_t a, uint32_t b) { #else uint32_t result = 0; for (int8_t i = 0; i < 2; i++) { - uint16_t ai = a >> (sizeof(uint16_t) * i); - uint16_t bi = b >> (sizeof(uint16_t) * i); - uint32_t intermediate = (uint32_t) ai + bi; + int16_t ai = (a >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int16_t bi = (b >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int32_t intermediate = (int32_t) ai + bi; if (intermediate > USHRT_MAX) { intermediate = USHRT_MAX; } - result |= ((uint16_t) intermediate) >> (sizeof(int16_t) * i); + result |= ((uint16_t) intermediate + 0x8000) << (sizeof(int16_t) * 8 * i); } return result; #endif -- cgit v1.2.3 From 2b0356c61f71afccbf10a9dcd3ad331bb4b856dd Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 Oct 2018 15:01:08 -0700 Subject: Disable framebuf by default on express builds. --- ports/atmel-samd/mpconfigport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 14f72ccfb..69a146c1f 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -207,7 +207,7 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PY_URE (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #ifndef MICROPY_PY_FRAMEBUF - #define MICROPY_PY_FRAMEBUF (1) + #define MICROPY_PY_FRAMEBUF (0) #endif #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1) -- cgit v1.2.3 From fd0ea85549826e8daccdb534abc3e49610eff836 Mon Sep 17 00:00:00 2001 From: Jerry Needell Date: Sat, 6 Oct 2018 08:03:27 -0400 Subject: add force_create to nrf filesystem_init() --- ports/nrf/supervisor/filesystem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/nrf/supervisor/filesystem.c b/ports/nrf/supervisor/filesystem.c index 1a3165a2d..b6611417d 100644 --- a/ports/nrf/supervisor/filesystem.c +++ b/ports/nrf/supervisor/filesystem.c @@ -36,7 +36,7 @@ static mp_vfs_mount_t _mp_vfs; static fs_user_mount_t _internal_vfs; -void filesystem_init(bool create_allowed) { +void filesystem_init(bool create_allowed, bool force_create) { // init the vfs object fs_user_mount_t *int_vfs = &_internal_vfs; int_vfs->flags = 0; @@ -45,7 +45,7 @@ void filesystem_init(bool create_allowed) { // try to mount the flash FRESULT res = f_mount(&int_vfs->fatfs); - if (res == FR_NO_FILESYSTEM && create_allowed) { + if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { // no filesystem so create a fresh one uint8_t working_buf[_MAX_SS]; res = f_mkfs(&int_vfs->fatfs, FM_FAT | FM_SFD, 4096, working_buf, sizeof(working_buf)); -- cgit v1.2.3 From cea079a0222685e1fd3652f7677ef441b9484c59 Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Sat, 6 Oct 2018 15:02:57 +0300 Subject: fix compilation errors in emitinlinethumb.c --- locale/circuitpython.pot | 73 ++++++++++++++++++++++++++++++++--------- locale/de_DE.po | 74 ++++++++++++++++++++++++++++++++--------- locale/en_US.po | 73 ++++++++++++++++++++++++++++++++--------- locale/es.po | 77 ++++++++++++++++++++++++++++++++++--------- locale/fil.po | 79 ++++++++++++++++++++++++++++++++++---------- locale/fr.po | 85 ++++++++++++++++++++++++++++++++++++------------ locale/pt_BR.po | 85 +++++++++++++++++++++++++++++++++++++----------- py/emitinlinethumb.c | 34 +++++++++---------- 8 files changed, 447 insertions(+), 133 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 232ad7c46..dca0801c8 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1095,38 +1091,85 @@ msgstr "" msgid "'data' requires integer arguments" msgstr "" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "" -#: py/emitinlinextensa.c:174 +#: py/emitinlinethumb.c:304 #, c-format -msgid "'%s' integer %d is not within range %d..%d" +msgid "'%s' integer 0x%x does not fit in mask 0x%x" msgstr "" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "" +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +msgid "branch not in range" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" diff --git a/locale/de_DE.po b/locale/de_DE.po index 790b23442..58cc33331 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -713,10 +713,6 @@ msgstr "Alle timer werden benutzt" msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1108,38 +1104,86 @@ msgstr "" msgid "'data' requires integer arguments" msgstr "" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "" -#: py/emitinlinextensa.c:174 +#: py/emitinlinethumb.c:304 #, c-format -msgid "'%s' integer %d is not within range %d..%d" +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" msgstr "" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "" +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "Kalibrierung ist außerhalb der Reichweite" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" diff --git a/locale/en_US.po b/locale/en_US.po index 6e576f150..6491f2f27 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1095,38 +1091,85 @@ msgstr "" msgid "'data' requires integer arguments" msgstr "" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "" -#: py/emitinlinextensa.c:174 +#: py/emitinlinethumb.c:304 #, c-format -msgid "'%s' integer %d is not within range %d..%d" +msgid "'%s' integer 0x%x does not fit in mask 0x%x" msgstr "" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "" +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +msgid "branch not in range" +msgstr "" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" diff --git a/locale/es.po b/locale/es.po index d524f7f10..28d68a013 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -719,10 +719,6 @@ msgstr "Todos los timers están siendo utilizados" msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "Baud rate demasiado alto para este periférico SPI" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1113,38 +1109,86 @@ msgstr "" msgid "'data' requires integer arguments" msgstr "" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "ord espera un carácter" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "" -#: py/emitinlinextensa.c:174 +#: py/emitinlinethumb.c:304 #, c-format -msgid "'%s' integer %d is not within range %d..%d" +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" msgstr "" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "" +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "El argumento de chr() no esta en el rango(256)" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" @@ -2410,3 +2454,6 @@ msgstr "" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Baud rate demasiado alto para este periférico SPI" diff --git a/locale/fil.po b/locale/fil.po index 7c8c4fdfe..d34e1b9f0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -719,10 +719,6 @@ msgstr "Lahat ng timer ginagamit" msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -743,7 +739,6 @@ msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 #: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 #: ports/nrf/common-hal/busio/UART.c:364 -#, fuzzy msgid "busio.UART not available" msgstr "" @@ -1119,38 +1114,88 @@ msgstr "'data' kailangan ng hindi bababa sa 2 argument" msgid "'data' requires integer arguments" msgstr "'data' kailangan ng integer arguments" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +#, fuzzy +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Xtensa assembly" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +#, fuzzy +msgid "parameters must be registers in sequence r0 to r3" msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "Inaasahan ng '%s' ang isang rehistro" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c:239 +#, fuzzy, c-format +msgid "'%s' expects an FPU register" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c:292 +#, fuzzy, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "Inaasahan ng '%s' ang isang integer" -#: py/emitinlinextensa.c:174 -#, c-format -msgid "'%s' integer %d is not within range %d..%d" +#: py/emitinlinethumb.c:304 +#, fuzzy, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" msgstr "'%s' integer %d ay wala sa sakop ng %d..%d" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:328 +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "'%s' umaasa ng label" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "label '%d' kailangan na i-define" +#: py/emitinlinethumb.c:806 +#, fuzzy, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "hindi sinusuportahan ang instruction ng Xtensa '%s' sa %d argumento" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "chr() arg wala sa sakop ng range(256)" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Xtensa assembly" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' integer %d ay wala sa sakop ng %d..%d" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" diff --git a/locale/fr.po b/locale/fr.po index 04d7a0665..4d5e126ad 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -715,10 +715,6 @@ msgstr "Tous les timers sont utilisés" msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1112,38 +1108,87 @@ msgstr "'data' nécessite au moins 2 arguments" msgid "'data' requires integer arguments" msgstr "'data' nécessite des arguments entiers" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +#, fuzzy +msgid "parameters must be registers in sequence r0 to r3" msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "'%s' attend un registre" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c:239 +#, fuzzy, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c:292 +#, fuzzy, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "'%s' attend un entier" -#: py/emitinlinextensa.c:174 -#, c-format -msgid "'%s' integer %d is not within range %d..%d" +#: py/emitinlinethumb.c:304 +#, fuzzy, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:328 +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "'%s' attend un label" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "label '%q' non supporté" +#: py/emitinlinethumb.c:806 +#, fuzzy, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "instruction Xtensa '%s' non supportée avec %d arguments" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "argument de chr() hors de la gamme range(256)" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" @@ -2425,10 +2470,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "'len' doit être un multiple de 4" - #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "la palette doit être longue de 32 octets" + +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "'len' doit être un multiple de 4" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 0a05d3db7..190c2a93d 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-07 02:07+0300\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -702,10 +702,6 @@ msgstr "Todos os periféricos I2C estão em uso" msgid "All SPI peripherals are in use" msgstr "Todos os periféricos SPI estão em uso" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "Taxa de transmissão muito alta para esse periférico SPI" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -1097,38 +1093,86 @@ msgstr "" msgid "'data' requires integer arguments" msgstr "" -#: py/emitinlinextensa.c:86 -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c:102 +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 -msgid "parameters must be registers in sequence a2 to a5" +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/emitinlinextensa.c:162 +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 #, c-format msgid "'%s' expects a register" msgstr "" -#: py/emitinlinextensa.c:169 +#: py/emitinlinethumb.c:211 +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c:239 +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c:292 +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 #, c-format msgid "'%s' expects an integer" msgstr "" -#: py/emitinlinextensa.c:174 +#: py/emitinlinethumb.c:304 #, c-format -msgid "'%s' integer %d is not within range %d..%d" +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/emitinlinethumb.c:328 +#, c-format +msgid "'%s' expects an address of the form [a, b]" msgstr "" -#: py/emitinlinextensa.c:182 +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 #, c-format msgid "'%s' expects a label" msgstr "" -#: py/emitinlinextensa.c:193 +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 msgid "label '%q' not defined" msgstr "" +#: py/emitinlinethumb.c:806 +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "Calibração está fora do intervalo" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + #: py/emitinlinextensa.c:327 #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" @@ -2009,19 +2053,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "Fase Inválida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "Número inválido de bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" @@ -2369,3 +2413,6 @@ msgstr "'S' e 'O' não são tipos de formato suportados" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "Muitos argumentos fornecidos com o formato dado" + +#~ msgid "Baud rate too high for this SPI peripheral" +#~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 577f65672..7f0ec6659 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -59,7 +59,7 @@ struct _emit_inline_asm_t { qstr *label_lookup; }; -STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const char *msg) { +STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const compressed_string_t *msg) { *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); } @@ -99,17 +99,17 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit, mp_uint_t type_s STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) { if (n_params > 4) { - emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly"); + emit_inline_thumb_error_msg(emit, translate("can only have up to 4 parameters to Thumb assembly")); return 0; } for (mp_uint_t i = 0; i < n_params; i++) { if (!MP_PARSE_NODE_IS_ID(pn_params[i])) { - emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); + emit_inline_thumb_error_msg(emit, translate("parameters must be registers in sequence r0 to r3")); return 0; } const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i])); if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) { - emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); + emit_inline_thumb_error_msg(emit, translate("parameters must be registers in sequence r0 to r3")); return 0; } } @@ -185,7 +185,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n if (r->reg > max_reg) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects at most r%d", op, max_reg)); + translate("'%s' expects at most r%d"), op, max_reg)); return 0; } else { return r->reg; @@ -194,7 +194,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n } emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects a register", op)); + translate("'%s' expects a register"), op)); return 0; } @@ -208,7 +208,7 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp } emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects a special register", op)); + translate("'%s' expects a special register"), op)); return 0; } @@ -227,7 +227,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars if (regno > 31) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects at most r%d", op, 31)); + translate("'%s' expects at most r%d"), op, 31)); return 0; } else { return regno; @@ -236,7 +236,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars malformed: emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects an FPU register", op)); + translate("'%s' expects an FPU register"), op)); return 0; } #endif @@ -289,19 +289,19 @@ STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_par return reglist; bad_arg: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects {r0, r1, ...}", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects {r0, r1, ...}"), op)); return 0; } STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, uint32_t fit_mask) { mp_obj_t o; if (!mp_parse_node_get_int_maybe(pn, &o)) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an integer"), op)); return 0; } uint32_t i = mp_obj_get_int_truncated(o); if ((i & (~fit_mask)) != 0) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer 0x%x does not fit in mask 0x%x", op, i, fit_mask)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' integer 0x%x does not fit in mask 0x%x"), op, i, fit_mask)); return 0; } return i; @@ -325,13 +325,13 @@ STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_ return true; bad_arg: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an address of the form [a, b]", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an address of the form [a, b]"), op)); return false; } STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { if (!MP_PARSE_NODE_IS_ID(pn)) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects a label"), op)); return 0; } qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn); @@ -342,7 +342,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_ } // only need to have the labels on the last pass if (emit->pass == MP_PASS_EMIT) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("label '%q' not defined"), label_qstr)); } return 0; } @@ -803,11 +803,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a return; unknown_op: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Thumb instruction '%s' with %d arguments", op_str, n_args)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("unsupported Thumb instruction '%s' with %d arguments"), op_str, n_args)); return; branch_not_in_range: - emit_inline_thumb_error_msg(emit, "branch not in range"); + emit_inline_thumb_error_msg(emit, translate("branch not in range")); return; } -- cgit v1.2.3 From a63555abc1ce07fe4e9420b5835865282adcd1db Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sun, 7 Oct 2018 15:37:57 +0200 Subject: py/builtinimport: Set __file__ on MPY modules This sets the __file__ property on MPY modules like how it's done on pure python modules. --- py/builtinimport.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/py/builtinimport.c b/py/builtinimport.c index fee875b60..6ed0a7594 100755 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -155,11 +155,9 @@ STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) { #endif #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_MODULE_FROZEN_MPY -STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) { +STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, const char *filename) { #if MICROPY_PY___FILE__ - // TODO - //qstr source_name = lex->source_name; - //mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); + mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(qstr_from_str(filename))); #endif // execute the module in its context @@ -222,7 +220,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // its data) in the list of frozen files, execute it. #if MICROPY_MODULE_FROZEN_MPY if (frozen_type == MP_FROZEN_MPY) { - do_execute_raw_code(module_obj, modref); + do_execute_raw_code(module_obj, modref, file_str); return; } #endif @@ -235,7 +233,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #if MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); - do_execute_raw_code(module_obj, raw_code); + do_execute_raw_code(module_obj, raw_code, file_str); return; } #endif -- cgit v1.2.3 From b897603cfa6f0f37dea4e1f9592a78d34d809f23 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sun, 7 Oct 2018 15:54:36 +0200 Subject: py/objboundmeth: Support __func__ property as in CPython This gives access to the function underlying the bound method. Used in the converted CPython stdlib logging.Formatter class to handle overrriding a default converter method bound to a class variable. The method becomes bound when accessed from an instance of that class. I didn't investigate why CircuitPython turns it into a bound method. --- py/objboundmeth.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/py/objboundmeth.c b/py/objboundmeth.c index b0df6a68a..a05680d41 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -92,6 +92,9 @@ STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR___name__) { mp_obj_bound_meth_t *o = MP_OBJ_TO_PTR(self_in); dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(o->meth)); + } else if (attr == MP_QSTR___func__) { + mp_obj_bound_meth_t *o = MP_OBJ_TO_PTR(self_in); + dest[0] = o->meth; } } #endif -- cgit v1.2.3 From db4a8f5d1a4d26b36d58ab2017501f63bd1cbe03 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Thu, 6 Sep 2018 23:07:00 +0200 Subject: modsys: exc_info: Add traceback Add traceback chain to sys.exec_info()[2]. No actual frame info is added, but just enough to recreate the printed exception traceback. Used by the unittest module which collects errors and failures and prints them at the end. --- py/builtinimport.c | 0 py/modsys.c | 2 +- py/obj.h | 1 + py/objexcept.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 1 deletion(-) mode change 100755 => 100644 py/builtinimport.c diff --git a/py/builtinimport.c b/py/builtinimport.c old mode 100755 new mode 100644 diff --git a/py/modsys.c b/py/modsys.c index e32841923..68e048d91 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -135,7 +135,7 @@ STATIC mp_obj_t mp_sys_exc_info(void) { t->items[0] = MP_OBJ_FROM_PTR(mp_obj_get_type(cur_exc)); t->items[1] = cur_exc; - t->items[2] = mp_const_none; + t->items[2] = mp_obj_exception_get_traceback_obj(cur_exc); return MP_OBJ_FROM_PTR(t); } MP_DEFINE_CONST_FUN_OBJ_0(mp_sys_exc_info_obj, mp_sys_exc_info); diff --git a/py/obj.h b/py/obj.h index 59cce0836..8b6772873 100644 --- a/py/obj.h +++ b/py/obj.h @@ -717,6 +717,7 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type); void mp_obj_exception_clear_traceback(mp_obj_t self_in); void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block); void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values); +mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in); mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); diff --git a/py/objexcept.c b/py/objexcept.c index 8bd6245a4..1ddc2174e 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -30,6 +30,7 @@ #include #include "py/objlist.h" +#include "py/objnamedtuple.h" #include "py/objstr.h" #include "py/objtuple.h" #include "py/objtype.h" @@ -531,3 +532,164 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values *values = self->traceback_data; } } + +#if MICROPY_PY_SYS_EXC_INFO +STATIC const mp_obj_namedtuple_type_t code_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_code, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 15, + .fields = { + MP_QSTR_co_argcount, + MP_QSTR_co_kwonlyargcount, + MP_QSTR_co_nlocals, + MP_QSTR_co_stacksize, + MP_QSTR_co_flags, + MP_QSTR_co_code, + MP_QSTR_co_consts, + MP_QSTR_co_names, + MP_QSTR_co_varnames, + MP_QSTR_co_freevars, + MP_QSTR_co_cellvars, + MP_QSTR_co_filename, + MP_QSTR_co_name, + MP_QSTR_co_firstlineno, + MP_QSTR_co_lnotab, + }, +}; + +STATIC mp_obj_t code_make_new(qstr file, qstr block) { + mp_obj_t elems[15] = { + mp_obj_new_int(0), // co_argcount + mp_obj_new_int(0), // co_kwonlyargcount + mp_obj_new_int(0), // co_nlocals + mp_obj_new_int(0), // co_stacksize + mp_obj_new_int(0), // co_flags + mp_obj_new_bytearray(0, NULL), // co_code + mp_obj_new_tuple(0, NULL), // co_consts + mp_obj_new_tuple(0, NULL), // co_names + mp_obj_new_tuple(0, NULL), // co_varnames + mp_obj_new_tuple(0, NULL), // co_freevars + mp_obj_new_tuple(0, NULL), // co_cellvars + MP_OBJ_NEW_QSTR(file), // co_filename + MP_OBJ_NEW_QSTR(block), // co_name + mp_obj_new_int(1), // co_firstlineno + mp_obj_new_bytearray(0, NULL), // co_lnotab + }; + + return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, 0, elems); +} + +STATIC const mp_obj_namedtuple_type_t frame_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_frame, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 8, + .fields = { + MP_QSTR_f_back, + MP_QSTR_f_builtins, + MP_QSTR_f_code, + MP_QSTR_f_globals, + MP_QSTR_f_lasti, + MP_QSTR_f_lineno, + MP_QSTR_f_locals, + MP_QSTR_f_trace, + }, +}; + +STATIC mp_obj_t frame_make_new(mp_obj_t f_code, int f_lineno) { + mp_obj_t elems[8] = { + mp_const_none, // f_back + mp_obj_new_dict(0), // f_builtins + f_code, // f_code + mp_obj_new_dict(0), // f_globals + mp_obj_new_int(0), // f_lasti + mp_obj_new_int(f_lineno), // f_lineno + mp_obj_new_dict(0), // f_locals + mp_const_none, // f_trace + }; + + return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, 0, elems); +} + +STATIC const mp_obj_namedtuple_type_t traceback_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_traceback, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 4, + .fields = { + MP_QSTR_tb_frame, + MP_QSTR_tb_lasti, + MP_QSTR_tb_lineno, + MP_QSTR_tb_next, + }, +}; + +STATIC mp_obj_t traceback_from_values(size_t *values, mp_obj_t tb_next) { + int lineno = values[1]; + + mp_obj_t elems[4] = { + frame_make_new(code_make_new(values[0], values[2]), lineno), + mp_obj_new_int(0), + mp_obj_new_int(lineno), + tb_next, + }; + + return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, 0, elems); +}; + +mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in) { + mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); + + if (!mp_obj_is_exception_instance(self)) { + return mp_const_none; + } + + size_t n, *values; + mp_obj_exception_get_traceback(self, &n, &values); + if (n == 0) { + return mp_const_none; + } + + mp_obj_t tb_next = mp_const_none; + + for (size_t i = 0; i < n; i += 3) { + tb_next = traceback_from_values(&values[i], tb_next); + } + + return tb_next; +} +#endif -- cgit v1.2.3 From 4b767ff080964a0774d9a4cb373ede3e97f209f2 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 12:24:24 +1100 Subject: Change WIZNET5K.isconnected to connected property --- shared-bindings/wiznet/__init__.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index 717ef4bc6..088335290 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -29,6 +29,7 @@ #include #include "py/objlist.h" +#include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" #include "py/mperrno.h" @@ -447,11 +448,22 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); -STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) { +STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { (void)self_in; return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); + +//| attribute:: connected +//| +//| is this device physically connected? + +const mp_obj_property_t wiznet5k_connected_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; /// \method ifconfig([(ip, subnet, gateway, dns)]) /// Get/set IP address, subnet mask, gateway and DNS. @@ -484,7 +496,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, }; STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); -- cgit v1.2.3 From 6e624b9c6a51e8b88eb22e62427c8e489f36072d Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 13:05:58 +1100 Subject: Split wiznet.WIZNET5K off into its own file --- ports/atmel-samd/Makefile | 2 +- shared-bindings/wiznet/__init__.c | 492 +---------------------------------- shared-bindings/wiznet/wiznet5k.c | 527 ++++++++++++++++++++++++++++++++++++++ shared-module/wiznet/wiznet5k.c | 0 4 files changed, 531 insertions(+), 490 deletions(-) create mode 100644 shared-bindings/wiznet/wiznet5k.c create mode 100644 shared-module/wiznet/wiznet5k.c diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index f01704a81..1ee0d79f0 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -421,7 +421,7 @@ SRC_SHARED_MODULE = \ ifeq ($(MICROPY_PY_NETWORK),1) SRC_SHARED_MODULE += socket/__init__.c network/__init__.c ifneq ($(MICROPY_PY_WIZNET5K),0) -SRC_SHARED_MODULE += wiznet/__init__.c +SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c endif endif diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index 088335290..e448d2ef1 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -31,502 +31,17 @@ #include "py/objlist.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "py/stream.h" -#include "py/mperrno.h" #include "py/mphal.h" -#include "lib/netutils/netutils.h" #include "shared-bindings/network/__init__.h" -#include "shared-bindings/digitalio/DigitalInOut.h" -#include "shared-bindings/digitalio/DriveMode.h" -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/random/__init__.h" -#if MICROPY_PY_WIZNET5K - -#include "ethernet/wizchip_conf.h" -#include "ethernet/socket.h" -#include "internet/dns/dns.h" - -/// \moduleref network - -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - busio_spi_obj_t *spi; - digitalio_digitalinout_obj_t cs; - digitalio_digitalinout_obj_t rst; - uint8_t socket_used; -} wiznet5k_obj_t; - -STATIC wiznet5k_obj_t wiznet5k_obj; - -STATIC void wiz_cris_enter(void) { - wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); -} - -STATIC void wiz_cris_exit(void) { - MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); -} - -STATIC void wiz_cs_select(void) { - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); -} - -STATIC void wiz_cs_deselect(void) { - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); -} - -STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { - (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); -} - -STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { - (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); -} - -STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { - uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; - uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); - DNS_init(0, buf); - mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); - m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); - if (ret == 1) { - // success - return 0; - } else { - // failure - return -2; - } -} - -STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->u_param.domain != MOD_NETWORK_AF_INET) { - *_errno = MP_EAFNOSUPPORT; - return -1; - } - - switch (socket->u_param.type) { - case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; - case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; - default: *_errno = MP_EINVAL; return -1; - } - - if (socket->u_param.fileno == -1) { - // get first unused socket number - for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { - if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { - wiznet5k_obj.socket_used |= (1 << sn); - socket->u_param.fileno = sn; - break; - } - } - if (socket->u_param.fileno == -1) { - // too many open sockets - *_errno = MP_EMFILE; - return -1; - } - } - - // WIZNET does not have a concept of pure "open socket". You need to know - // if it's a server or client at the time of creation of the socket. - // So, we defer the open until we know what kind of socket we want. - - // use "domain" to indicate that this socket has not yet been opened - socket->u_param.domain = 0; - - return 0; -} - -STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { - uint8_t sn = (uint8_t)socket->u_param.fileno; - if (sn < _WIZCHIP_SOCK_NUM_) { - wiznet5k_obj.socket_used &= ~(1 << sn); - WIZCHIP_EXPORT(close)(sn); - } -} - -STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // open the socket in server mode (if port != 0) - mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // indicate that this socket has been opened - socket->u_param.domain = 1; - - // success - return 0; -} - -STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return 0; -} - -STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { - for (;;) { - int sr = getSn_SR((uint8_t)socket->u_param.fileno); - if (sr == SOCK_ESTABLISHED) { - socket2->u_param = socket->u_param; - getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); - *port = getSn_PORT(socket2->u_param.fileno); - - // WIZnet turns the listening socket into the client socket, so we - // need to re-bind and re-listen on another socket for the server. - // TODO handle errors, especially no-more-sockets error - socket->u_param.domain = MOD_NETWORK_AF_INET; - socket->u_param.fileno = -1; - int _errno2; - if (wiznet5k_socket_socket(socket, &_errno2) != 0) { - //printf("(bad resocket %d)\n", _errno2); - } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { - //printf("(bad rebind %d)\n", _errno2); - } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { - //printf("(bad relisten %d)\n", _errno2); - } - - return 0; - } - if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { - wiznet5k_socket_close(socket); - *_errno = MP_ENOTCONN; // ?? - return -1; - } - mp_hal_delay_ms(1); - } -} - -STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - - // now connect - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // success - return 0; -} - -STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { - if (socket->u_param.domain == 0) { - // socket not opened; use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - } - - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { - uint16_t port2; - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); - MP_THREAD_GIL_ENTER(); - *port = port2; - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; -} - -STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; - - /* - if (timeout_ms == 0) { - // set non-blocking mode - uint8_t arg = SOCK_IO_NONBLOCK; - WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); - } - */ -} - -STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { - if (request == MP_STREAM_POLL) { - int ret = 0; - if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { - ret |= MP_STREAM_POLL_RD; - } - if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { - ret |= MP_STREAM_POLL_WR; - } - return ret; - } else { - *_errno = MP_EINVAL; - return MP_STREAM_ERROR; - } -} - -#if 0 -STATIC void wiznet5k_socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - wiznet5k_socket_obj_t *self = self_in; - print(env, "", self->sn, getSn_MR(self->sn)); -} - -STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { - mp_int_t ret = WIZCHIP_EXPORT(disconnect)(self->sn); - return 0; -} -#endif - -void create_random_mac_address(uint8_t *mac) { - uint32_t rb1 = shared_modules_random_getrandbits(24); - uint32_t rb2 = shared_modules_random_getrandbits(24); - // first octet has multicast bit (0) cleared and local bit (1) set - // everything else is just set randomly - mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; - mac[1] = (uint8_t)(rb1 >> 8); - mac[2] = (uint8_t)(rb1); - mac[3] = (uint8_t)(rb2 >> 16); - mac[4] = (uint8_t)(rb2 >> 8); - mac[5] = (uint8_t)(rb2); -} - -/******************************************************************************/ -// MicroPython bindings - -/// \classmethod \constructor(spi, pin_cs, pin_rst) -/// Create and return a WIZNET5K object. -STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 3, 3, false); - - // init the wiznet5k object - wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; - wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = MP_OBJ_TO_PTR(args[0]); - common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, args[1]); - common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, args[2]); - wiznet5k_obj.socket_used = 0; - - /*!< SPI configuration */ - // XXX probably should check if the provided SPI is already configured, and - // if so skip configuration? - - common_hal_busio_spi_configure(wiznet5k_obj.spi, - 10000000, // BAUDRATE 10MHz - 1, // HIGH POLARITY - 1, // SECOND PHASE TRANSITION - 8 // 8 BITS - ); - - common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); - common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL); - - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); - mp_hal_delay_us(10); // datasheet says 2us - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); - mp_hal_delay_ms(160); // datasheet says 150ms - - reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); - reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); - reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); - - uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 2k buffer for each socket - ctlwizchip(CW_INIT_WIZCHIP, sn_size); - - // set some sensible default values; they are configurable using ifconfig method - wiz_NetInfo netinfo = { - .ip = {192, 168, 0, 18}, - .sn = {255, 255, 255, 0}, - .gw = {192, 168, 0, 1}, - .dns = {8, 8, 8, 8}, // Google public DNS - .dhcp = NETINFO_STATIC, - }; - create_random_mac_address(netinfo.mac); - ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); - - // seems we need a small delay after init - mp_hal_delay_ms(250); - - // register with network module - network_module_register_nic(&wiznet5k_obj); - - // return wiznet5k object - return &wiznet5k_obj; -} - -/// \method regs() -/// Dump WIZNET5K registers. -STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { - //wiznet5k_obj_t *self = self_in; - printf("Wiz CREG:"); - for (int i = 0; i < 0x50; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_WIZNET5K == 5200 - uint32_t reg = i; - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - for (int sn = 0; sn < 4; ++sn) { - printf("\nWiz SREG[%d]:", sn); - for (int i = 0; i < 0x30; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_WIZNET5K == 5200 - uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - } - printf("\n"); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); - -STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { - (void)self_in; - return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); - -//| attribute:: connected -//| -//| is this device physically connected? - -const mp_obj_property_t wiznet5k_connected_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -/// \method ifconfig([(ip, subnet, gateway, dns)]) -/// Get/set IP address, subnet mask, gateway and DNS. -STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { - wiz_NetInfo netinfo; - ctlnetwork(CN_GET_NETINFO, &netinfo); - if (n_args == 1) { - // get - mp_obj_t tuple[4] = { - netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG), - netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG), - }; - return mp_obj_new_tuple(4, tuple); - } else { - // set - mp_obj_t *items; - mp_obj_get_array_fixed_n(args[1], 4, &items); - netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG); - ctlnetwork(CN_SET_NETINFO, &netinfo); - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); - -STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); - -const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_WIZNET5K, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_dict_t*)&wiznet5k_locals_dict, - }, - .gethostbyname = wiznet5k_gethostbyname, - .socket = wiznet5k_socket_socket, - .close = wiznet5k_socket_close, - .bind = wiznet5k_socket_bind, - .listen = wiznet5k_socket_listen, - .accept = wiznet5k_socket_accept, - .connect = wiznet5k_socket_connect, - .send = wiznet5k_socket_send, - .recv = wiznet5k_socket_recv, - .sendto = wiznet5k_socket_sendto, - .recvfrom = wiznet5k_socket_recvfrom, - .setsockopt = wiznet5k_socket_setsockopt, - .settimeout = wiznet5k_socket_settimeout, - .ioctl = wiznet5k_socket_ioctl, -}; +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; STATIC const mp_rom_map_elem_t mp_module_wiznet_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) }, +#ifdef MICROPY_PY_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +#endif // MICROPY_PY_WIZNET5K }; STATIC MP_DEFINE_CONST_DICT(mp_module_wiznet_globals, mp_module_wiznet_globals_table); @@ -535,4 +50,3 @@ const mp_obj_module_t wiznet_module = { .globals = (mp_obj_dict_t*)&mp_module_wiznet_globals, }; -#endif // MICROPY_PY_WIZNET5K diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c new file mode 100644 index 000000000..967e7d0f4 --- /dev/null +++ b/shared-bindings/wiznet/wiznet5k.c @@ -0,0 +1,527 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "lib/netutils/netutils.h" + +#include "shared-bindings/network/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/random/__init__.h" + +#if MICROPY_PY_WIZNET5K + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" + +/// \moduleref network + +typedef struct _wiznet5k_obj_t { + mp_obj_base_t base; + mp_uint_t cris_state; + busio_spi_obj_t *spi; + digitalio_digitalinout_obj_t cs; + digitalio_digitalinout_obj_t rst; + uint8_t socket_used; +} wiznet5k_obj_t; + +STATIC wiznet5k_obj_t wiznet5k_obj; + +STATIC void wiz_cris_enter(void) { + wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); +} + +STATIC void wiz_cris_exit(void) { + MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); +} + +STATIC void wiz_cs_select(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); +} + +STATIC void wiz_cs_deselect(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); +} + +STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); +} + +STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); +} + +STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; + uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); + DNS_init(0, buf); + mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); + m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + if (ret == 1) { + // success + return 0; + } else { + // failure + return -2; + } +} + +STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { + if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + *_errno = MP_EAFNOSUPPORT; + return -1; + } + + switch (socket->u_param.type) { + case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; + case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; + default: *_errno = MP_EINVAL; return -1; + } + + if (socket->u_param.fileno == -1) { + // get first unused socket number + for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { + wiznet5k_obj.socket_used |= (1 << sn); + socket->u_param.fileno = sn; + break; + } + } + if (socket->u_param.fileno == -1) { + // too many open sockets + *_errno = MP_EMFILE; + return -1; + } + } + + // WIZNET does not have a concept of pure "open socket". You need to know + // if it's a server or client at the time of creation of the socket. + // So, we defer the open until we know what kind of socket we want. + + // use "domain" to indicate that this socket has not yet been opened + socket->u_param.domain = 0; + + return 0; +} + +STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { + uint8_t sn = (uint8_t)socket->u_param.fileno; + if (sn < _WIZCHIP_SOCK_NUM_) { + wiznet5k_obj.socket_used &= ~(1 << sn); + WIZCHIP_EXPORT(close)(sn); + } +} + +STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // open the socket in server mode (if port != 0) + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // indicate that this socket has been opened + socket->u_param.domain = 1; + + // success + return 0; +} + +STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { + mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return 0; +} + +STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { + for (;;) { + int sr = getSn_SR((uint8_t)socket->u_param.fileno); + if (sr == SOCK_ESTABLISHED) { + socket2->u_param = socket->u_param; + getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); + *port = getSn_PORT(socket2->u_param.fileno); + + // WIZnet turns the listening socket into the client socket, so we + // need to re-bind and re-listen on another socket for the server. + // TODO handle errors, especially no-more-sockets error + socket->u_param.domain = MOD_NETWORK_AF_INET; + socket->u_param.fileno = -1; + int _errno2; + if (wiznet5k_socket_socket(socket, &_errno2) != 0) { + //printf("(bad resocket %d)\n", _errno2); + } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { + //printf("(bad rebind %d)\n", _errno2); + } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { + //printf("(bad relisten %d)\n", _errno2); + } + + return 0; + } + if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { + wiznet5k_socket_close(socket); + *_errno = MP_ENOTCONN; // ?? + return -1; + } + mp_hal_delay_ms(1); + } +} + +STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + + // now connect + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // success + return 0; +} + +STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { + if (socket->u_param.domain == 0) { + // socket not opened; use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + } + + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { + uint16_t port2; + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); + MP_THREAD_GIL_ENTER(); + *port = port2; + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +STATIC int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; +} + +STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; + + /* + if (timeout_ms == 0) { + // set non-blocking mode + uint8_t arg = SOCK_IO_NONBLOCK; + WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); + } + */ +} + +STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + if (request == MP_STREAM_POLL) { + int ret = 0; + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_RD; + } + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_WR; + } + return ret; + } else { + *_errno = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +#if 0 +STATIC void wiznet5k_socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + wiznet5k_socket_obj_t *self = self_in; + print(env, "", self->sn, getSn_MR(self->sn)); +} + +STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { + mp_int_t ret = WIZCHIP_EXPORT(disconnect)(self->sn); + return 0; +} +#endif + +void create_random_mac_address(uint8_t *mac) { + uint32_t rb1 = shared_modules_random_getrandbits(24); + uint32_t rb2 = shared_modules_random_getrandbits(24); + // first octet has multicast bit (0) cleared and local bit (1) set + // everything else is just set randomly + mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; + mac[1] = (uint8_t)(rb1 >> 8); + mac[2] = (uint8_t)(rb1); + mac[3] = (uint8_t)(rb2 >> 16); + mac[4] = (uint8_t)(rb2 >> 8); + mac[5] = (uint8_t)(rb2); +} + +/******************************************************************************/ +// MicroPython bindings + +/// \classmethod \constructor(spi, pin_cs, pin_rst) +/// Create and return a WIZNET5K object. +STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 3, 3, false); + + // init the wiznet5k object + wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; + wiznet5k_obj.cris_state = 0; + wiznet5k_obj.spi = MP_OBJ_TO_PTR(args[0]); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, args[1]); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, args[2]); + wiznet5k_obj.socket_used = 0; + + /*!< SPI configuration */ + // XXX probably should check if the provided SPI is already configured, and + // if so skip configuration? + + common_hal_busio_spi_configure(wiznet5k_obj.spi, + 10000000, // BAUDRATE 10MHz + 1, // HIGH POLARITY + 1, // SECOND PHASE TRANSITION + 8 // 8 BITS + ); + + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL); + + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); + mp_hal_delay_us(10); // datasheet says 2us + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); + mp_hal_delay_ms(160); // datasheet says 150ms + + reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); + reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); + reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); + + uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 2k buffer for each socket + ctlwizchip(CW_INIT_WIZCHIP, sn_size); + + // set some sensible default values; they are configurable using ifconfig method + wiz_NetInfo netinfo = { + .ip = {192, 168, 0, 18}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 0, 1}, + .dns = {8, 8, 8, 8}, // Google public DNS + .dhcp = NETINFO_STATIC, + }; + create_random_mac_address(netinfo.mac); + ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); + + // seems we need a small delay after init + mp_hal_delay_ms(250); + + // register with network module + network_module_register_nic(&wiznet5k_obj); + + // return wiznet5k object + return &wiznet5k_obj; +} + +/// \method regs() +/// Dump WIZNET5K registers. +STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { + //wiznet5k_obj_t *self = self_in; + printf("Wiz CREG:"); + for (int i = 0; i < 0x50; ++i) { + if (i % 16 == 0) { + printf("\n %04x:", i); + } + #if MICROPY_PY_WIZNET5K == 5200 + uint32_t reg = i; + #else + uint32_t reg = _W5500_IO_BASE_ | i << 8; + #endif + printf(" %02x", WIZCHIP_READ(reg)); + } + for (int sn = 0; sn < 4; ++sn) { + printf("\nWiz SREG[%d]:", sn); + for (int i = 0; i < 0x30; ++i) { + if (i % 16 == 0) { + printf("\n %04x:", i); + } + #if MICROPY_PY_WIZNET5K == 5200 + uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); + #else + uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; + #endif + printf(" %02x", WIZCHIP_READ(reg)); + } + } + printf("\n"); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); + +STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); + +//| attribute:: connected +//| +//| is this device physically connected? + +const mp_obj_property_t wiznet5k_connected_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +/// \method ifconfig([(ip, subnet, gateway, dns)]) +/// Get/set IP address, subnet mask, gateway and DNS. +STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { + wiz_NetInfo netinfo; + ctlnetwork(CN_GET_NETINFO, &netinfo); + if (n_args == 1) { + // get + mp_obj_t tuple[4] = { + netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG), + }; + return mp_obj_new_tuple(4, tuple); + } else { + // set + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 4, &items); + netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG); + ctlnetwork(CN_SET_NETINFO, &netinfo); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); + +STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); + +const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { + .base = { + { &mp_type_type }, + .name = MP_QSTR_WIZNET5K, + .make_new = wiznet5k_make_new, + .locals_dict = (mp_obj_dict_t*)&wiznet5k_locals_dict, + }, + .gethostbyname = wiznet5k_gethostbyname, + .socket = wiznet5k_socket_socket, + .close = wiznet5k_socket_close, + .bind = wiznet5k_socket_bind, + .listen = wiznet5k_socket_listen, + .accept = wiznet5k_socket_accept, + .connect = wiznet5k_socket_connect, + .send = wiznet5k_socket_send, + .recv = wiznet5k_socket_recv, + .sendto = wiznet5k_socket_sendto, + .recvfrom = wiznet5k_socket_recvfrom, + .setsockopt = wiznet5k_socket_setsockopt, + .settimeout = wiznet5k_socket_settimeout, + .ioctl = wiznet5k_socket_ioctl, +}; + +#endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3 From 9b36d33df142d4a3dd2c238799e227c05b537d95 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 13:12:04 +1100 Subject: move random mac address function into network module --- shared-bindings/wiznet/wiznet5k.c | 18 +++------------- shared-module/network/__init__.c | 43 +++++++++++++++++++++++++++++++++++++++ shared-module/network/__init__.h | 28 +++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 shared-module/network/__init__.h diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 967e7d0f4..558867264 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -40,7 +40,8 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/busio/SPI.h" -#include "shared-bindings/random/__init__.h" + +#include "shared-module/network/__init__.h" #if MICROPY_PY_WIZNET5K @@ -336,19 +337,6 @@ STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { } #endif -void create_random_mac_address(uint8_t *mac) { - uint32_t rb1 = shared_modules_random_getrandbits(24); - uint32_t rb2 = shared_modules_random_getrandbits(24); - // first octet has multicast bit (0) cleared and local bit (1) set - // everything else is just set randomly - mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; - mac[1] = (uint8_t)(rb1 >> 8); - mac[2] = (uint8_t)(rb1); - mac[3] = (uint8_t)(rb2 >> 16); - mac[4] = (uint8_t)(rb2 >> 8); - mac[5] = (uint8_t)(rb2); -} - /******************************************************************************/ // MicroPython bindings @@ -400,7 +388,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size .dns = {8, 8, 8, 8}, // Google public DNS .dhcp = NETINFO_STATIC, }; - create_random_mac_address(netinfo.mac); + network_module_create_random_mac_address(netinfo.mac); ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); // seems we need a small delay after init diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c index e69de29bb..7e3b7fd26 100644 --- a/shared-module/network/__init__.c +++ b/shared-module/network/__init__.c @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Nick Moore + * + * 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 "py/mphal.h" + +#include "shared-bindings/random/__init__.h" + +void network_module_create_random_mac_address(uint8_t *mac) { + uint32_t rb1 = shared_modules_random_getrandbits(24); + uint32_t rb2 = shared_modules_random_getrandbits(24); + // first octet has multicast bit (0) cleared and local bit (1) set + // everything else is just set randomly + mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; + mac[1] = (uint8_t)(rb1 >> 8); + mac[2] = (uint8_t)(rb1); + mac[3] = (uint8_t)(rb2 >> 16); + mac[4] = (uint8_t)(rb2 >> 8); + mac[5] = (uint8_t)(rb2); +} + diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h new file mode 100644 index 000000000..13f800fb0 --- /dev/null +++ b/shared-module/network/__init__.h @@ -0,0 +1,28 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Nick Moore + * + * 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. + */ + +void network_module_create_random_mac_address(uint8_t *mac); + -- cgit v1.2.3 From a1d539941dfd39aa2d6c54d527212a391e08d3c6 Mon Sep 17 00:00:00 2001 From: Carlos Date: Mon, 8 Oct 2018 22:05:30 -0500 Subject: Translation of strings on Unix directory --- locale/es.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locale/es.po b/locale/es.po index 28d68a013..ff5471c74 100644 --- a/locale/es.po +++ b/locale/es.po @@ -848,15 +848,15 @@ msgstr "Longitud de string UUID inválida" #: ports/unix/modffi.c:138 msgid "Unknown type" -msgstr "" +msgstr "Tipo desconocido" #: ports/unix/modffi.c:207 ports/unix/modffi.c:265 msgid "Error in ffi_prep_cif" -msgstr "" +msgstr "Error en ffi_prep_cif" #: ports/unix/modffi.c:270 msgid "ffi_prep_closure_loc" -msgstr "" +msgstr "ffi_prep_closure_loc" #: ports/unix/modffi.c:413 msgid "Don't know how to pass object to native function" @@ -865,30 +865,30 @@ msgstr "" #: ports/unix/modusocket.c:474 #, c-format msgid "[addrinfo error %d]" -msgstr "" +msgstr "[addrinfo error %d]" #: py/argcheck.c:44 msgid "function does not take keyword arguments" -msgstr "" +msgstr "la función no tiene argumentos por palabra clave" #: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 #, c-format msgid "function takes %d positional arguments but %d were given" -msgstr "" +msgstr "la función toma %d argumentos posicionales pero le fueron dados %d" #: py/argcheck.c:64 #, c-format msgid "function missing %d required positional arguments" -msgstr "" +msgstr "a la función le hacen falta %d argumentos posicionales requeridos" #: py/argcheck.c:72 #, c-format msgid "function expected at most %d arguments, got %d" -msgstr "" +msgstr "la función esperaba a lo sumo %d argumentos, tiene %d" #: py/argcheck.c:97 msgid "'%q' argument required" -msgstr "" +msgstr "argumento '%q' requerido" #: py/argcheck.c:122 msgid "extra positional arguments given" @@ -912,11 +912,11 @@ msgstr "" #: py/bc.c:197 py/bc.c:215 msgid "unexpected keyword argument" -msgstr "" +msgstr "argumento por palabra clave inesperado" #: py/bc.c:199 msgid "keywords must be strings" -msgstr "" +msgstr "palabras clave deben ser strings" #: py/bc.c:206 py/objnamedtuple.c:138 msgid "function got multiple values for argument '%q'" -- cgit v1.2.3 From a60700b1c5a97047b26290745dae26025e3514cc Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 16:28:30 +1100 Subject: Get DHCP working ... --- drivers/wiznet5k/ethernet/socket.c | 11 ++--------- drivers/wiznet5k/internet/dhcp/dhcp.c | 21 +++++++++++---------- drivers/wiznet5k/internet/dhcp/dhcp.h | 6 ++++-- ports/atmel-samd/Makefile | 1 + shared-bindings/wiznet/wiznet5k.c | 31 ++++++++++++++++++++++++------- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/drivers/wiznet5k/ethernet/socket.c b/drivers/wiznet5k/ethernet/socket.c index 4ca7113e8..bea98601d 100644 --- a/drivers/wiznet5k/ethernet/socket.c +++ b/drivers/wiznet5k/ethernet/socket.c @@ -6,6 +6,7 @@ //! \version 1.0.3 //! \date 2013/10/21 //! \par Revision history +//! <2018/10/09> Nick Moore fixes for CircuitPython //! <2014/05/01> V1.0.3. Refer to M20140501 //! 1. Implicit type casting -> Explicit type casting. //! 2. replace 0x01 with PACK_REMAINED in recvfrom() @@ -393,15 +394,7 @@ int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t CHECK_SOCKDATA(); //M20140501 : For avoiding fatal error on memory align mismatched //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; - { - uint32_t taddr; - taddr = ((uint32_t)addr[0]) & 0x000000FF; - taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); - taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); - taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); - if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; - } - // + if ((addr[0] | addr[1] | addr[2] | addr[3]) == 0) return SOCKERR_IPINVALID; if(port == 0) return SOCKERR_PORTZERO; tmp = getSn_SR(sn); if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.c b/drivers/wiznet5k/internet/dhcp/dhcp.c index 574758259..c56e64474 100644 --- a/drivers/wiznet5k/internet/dhcp/dhcp.c +++ b/drivers/wiznet5k/internet/dhcp/dhcp.c @@ -6,6 +6,7 @@ //! \version 1.1.0 //! \date 2013/11/18 //! \par Revision history +//! <2018/10/09> Modified by Nick Moore for CircuitPython //! <2013/11/18> 1st Release //! <2012/12/20> V1.1.0 //! 1. Optimize code @@ -51,7 +52,7 @@ //#include "Ethernet/socket.h" //#include "Internet/DHCP/dhcp.h" -#include "../../Ethernet/socket.h" +#include "../../ethernet/socket.h" #include "dhcp.h" /* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ @@ -408,7 +409,7 @@ void send_DHCP_DISCOVER(void) printf("> Send DHCP_DISCOVER\r\n"); #endif - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } /* SEND DHCP REQUEST */ @@ -503,7 +504,7 @@ void send_DHCP_REQUEST(void) printf("> Send DHCP_REQUEST\r\n"); #endif - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } @@ -564,7 +565,7 @@ void send_DHCP_DECLINE(void) printf("\r\n> Send DHCP_DECLINE\r\n"); #endif - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } /* PARSE REPLY pDHCPMSG */ @@ -581,13 +582,13 @@ int8_t parseDHCPMSG(void) if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) { - len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); + len = WIZCHIP_EXPORT(recvfrom)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); #ifdef _DHCP_DEBUG_ printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); #endif } else return 0; - if (svr_port == DHCP_SERVER_PORT) { + if (svr_port == DHCP_SERVER_PORT) { // compare mac address if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || @@ -677,7 +678,7 @@ uint8_t DHCP_run(void) if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) - socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + WIZCHIP_EXPORT(socket)(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); ret = DHCP_RUNNING; type = parseDHCPMSG(); @@ -801,7 +802,7 @@ uint8_t DHCP_run(void) void DHCP_stop(void) { - close(DHCP_SOCKET); + WIZCHIP_EXPORT(close)(DHCP_SOCKET); dhcp_state = STATE_DHCP_STOP; } @@ -869,7 +870,7 @@ int8_t check_DHCP_leasedIP(void) // IP conflict detection : ARP request - ARP reply // Broadcasting ARP Request for check the IP conflict using UDP sendto() function - ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + ret = WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); // RCR value restore setRCR(tmp); @@ -893,7 +894,7 @@ int8_t check_DHCP_leasedIP(void) } } -void DHCP_init(uint8_t s, uint8_t * buf) +void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf) { uint8_t zeroip[4] = {0,0,0,0}; getSHAR(DHCP_CHADDR); diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.h b/drivers/wiznet5k/internet/dhcp/dhcp.h index ee154d506..881bf5a6c 100644 --- a/drivers/wiznet5k/internet/dhcp/dhcp.h +++ b/drivers/wiznet5k/internet/dhcp/dhcp.h @@ -55,7 +55,7 @@ /* Retry to processing DHCP */ #define MAX_DHCP_RETRY 2 ///< Maximum retry count -#define DHCP_WAIT_TIME 10 ///< Wait Time 10s +#define DHCP_WAIT_TIME 3 ///< Wait Time 3s (was 10s) /* UDP port numbers for DHCP */ #define DHCP_SERVER_PORT 67 ///< DHCP server port number @@ -78,12 +78,14 @@ enum DHCP_STOPPED ///< Stop processing DHCP protocol }; +#define DHCP_INIT_BUFFER_TYPE uint32_t +#define DHCP_INIT_BUFFER_SIZE (137) /* * @brief DHCP client initialization (outside of the main loop) * @param s - socket number * @param buf - buffer for processing DHCP message */ -void DHCP_init(uint8_t s, uint8_t * buf); +void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf); /* * @brief DHCP 1s Tick Timer handler diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 1ee0d79f0..3a460ed8c 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -300,6 +300,7 @@ SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ ethernet/wizchip_conf.c \ ethernet/socket.c \ internet/dns/dns.c \ + internet/dhcp/dhcp.c \ ) endif # MICROPY_PY_WIZNET5K diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 558867264..b561806ae 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -48,6 +48,7 @@ #include "ethernet/wizchip_conf.h" #include "ethernet/socket.h" #include "internet/dns/dns.h" +#include "internet/dhcp/dhcp.h" /// \moduleref network @@ -337,6 +338,24 @@ STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { } #endif +static void wiznet5k_try_dhcp(void) { + DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; + + // Set up the socket to listen on UDP 68 before calling DHCP_init + WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); + DHCP_init(0, dhcp_buf); + + // try a few times for DHCP ... XXX this should be asynchronous. + for (int i=0; i<10; i++) { + DHCP_time_handler(); + int dhcp_state = DHCP_run(); + if (dhcp_state == DHCP_IP_LEASED || dhcp_state == DHCP_IP_CHANGED) break; + mp_hal_delay_ms(1000); + } + DHCP_stop(); + WIZCHIP_EXPORT(close)(0); +} + /******************************************************************************/ // MicroPython bindings @@ -377,16 +396,12 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); - uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 2k buffer for each socket + // 2k buffer for each socket + uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; ctlwizchip(CW_INIT_WIZCHIP, sn_size); - // set some sensible default values; they are configurable using ifconfig method wiz_NetInfo netinfo = { - .ip = {192, 168, 0, 18}, - .sn = {255, 255, 255, 0}, - .gw = {192, 168, 0, 1}, - .dns = {8, 8, 8, 8}, // Google public DNS - .dhcp = NETINFO_STATIC, + .dhcp = NETINFO_DHCP, }; network_module_create_random_mac_address(netinfo.mac); ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); @@ -394,6 +409,8 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size // seems we need a small delay after init mp_hal_delay_ms(250); + wiznet5k_try_dhcp(); + // register with network module network_module_register_nic(&wiznet5k_obj); -- cgit v1.2.3 From ae47c23aa6a1d86abef4d862016b12791009e780 Mon Sep 17 00:00:00 2001 From: Enrico Paganin Date: Thu, 4 Oct 2018 14:05:39 +0200 Subject: Add Italian translation Adding first draft, it needs to be reviewed --- locale/it_IT.po | 2459 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2459 insertions(+) create mode 100644 locale/it_IT.po diff --git a/locale/it_IT.po b/locale/it_IT.po new file mode 100644 index 000000000..dd8b41f76 --- /dev/null +++ b/locale/it_IT.po @@ -0,0 +1,2459 @@ +# Italian translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Enrico Paganin , 2018 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-10-07 10:54+0200\n" +"PO-Revision-Date: 2018-10-02 16:27+0200\n" +"Last-Translator: Enrico Paganin \n" +"Language-Team: \n" +"Language: it_IT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: extmod/machine_i2c.c:299 +msgid "invalid I2C peripheral" +msgstr "periferica I2C invalida" + +#: extmod/machine_i2c.c:340 extmod/machine_i2c.c:354 extmod/machine_i2c.c:368 +#: extmod/machine_i2c.c:392 +msgid "I2C operation not supported" +msgstr "operazione I2C non supportata" + +#: extmod/machine_mem.c:45 ports/unix/modmachine.c:53 +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "l'indirizzo %08x non è allineato a %d bytes" + +#: extmod/machine_spi.c:57 +msgid "invalid SPI peripheral" +msgstr "periferica SPI invalida" + +#: extmod/machine_spi.c:124 +msgid "buffers must be the same length" +msgstr "i buffer devono essere della stessa lunghezza" + +#: extmod/machine_spi.c:207 +msgid "bits must be 8" +msgstr "i bit devono essere 8" + +#: extmod/machine_spi.c:210 +msgid "firstbit must be MSB" +msgstr "il primo bit deve essere il più significativo (MSB)" + +#: extmod/machine_spi.c:215 +msgid "must specify all of sck/mosi/miso" +msgstr "è necessario specificare tutte le sck/mosi/miso" + +#: extmod/modframebuf.c:299 +msgid "invalid format" +msgstr "formato non valido" + +#: extmod/modubinascii.c:38 extmod/moduhashlib.c:102 +msgid "a bytes-like object is required" +msgstr "un oggetto byte-like è richiesto" + +#: extmod/modubinascii.c:90 +msgid "odd-length string" +msgstr "stringa di lunghezza dispari" + +#: extmod/modubinascii.c:101 +msgid "non-hex digit found" +msgstr "trovata cifra non esadecimale" + +#: extmod/modubinascii.c:169 +msgid "incorrect padding" +msgstr "padding incorretto" + +#: extmod/moductypes.c:122 +msgid "syntax error in uctypes descriptor" +msgstr "errore di sintassi nel descrittore uctypes" + +#: extmod/moductypes.c:219 +msgid "Cannot unambiguously get sizeof scalar" +msgstr "Impossibile ricavare la grandezza scalare di sizeof inequivocabilmente" + +#: extmod/moductypes.c:397 +msgid "struct: no fields" +msgstr "struct: nessun campo" + +#: extmod/moductypes.c:530 +msgid "struct: cannot index" +msgstr "struct: impossibile indicizzare" + +#: extmod/moductypes.c:544 +msgid "struct: index out of range" +msgstr "struct: indice fuori intervallo" + +#: extmod/moduheapq.c:38 +msgid "heap must be a list" +msgstr "l'heap deve essere una lista" + +#: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 +msgid "empty heap" +msgstr "heap vuoto" + +#: extmod/modujson.c:281 +msgid "syntax error in JSON" +msgstr "errore di sintassi nel JSON" + +#: extmod/modure.c:161 +msgid "Splitting with sub-captures" +msgstr "Suddivisione con sotto-catture" + +#: extmod/modure.c:207 +msgid "Error in regex" +msgstr "Errore nella regex" + +#: extmod/modussl_axtls.c:81 +msgid "invalid key" +msgstr "chiave non valida" + +#: extmod/modussl_axtls.c:87 +msgid "invalid cert" +msgstr "certificato non valido" + +#: extmod/modutimeq.c:131 +msgid "queue overflow" +msgstr "overflow della coda" + +#: extmod/moduzlib.c:98 +msgid "compression header" +msgstr "compressione dell'header" + +#: extmod/uos_dupterm.c:120 +msgid "invalid dupterm index" +msgstr "indice dupterm non valido" + +#: extmod/vfs_fat.c:426 py/moduerrno.c:150 +msgid "Read-only filesystem" +msgstr "Filesystem in sola lettura" + +#: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 +msgid "I/O operation on closed file" +msgstr "operazione I/O su file chiuso" + +#: lib/embed/abort_.c:8 +msgid "abort() called" +msgstr "abort() chiamato" + +#: lib/netutils/netutils.c:83 +msgid "invalid arguments" +msgstr "argomenti non validi" + +#: lib/utils/pyexec.c:97 py/builtinimport.c:253 +msgid "script compilation not supported" +msgstr "compilazione dello scrip non suportata" + +#: main.c:143 +msgid " output:\n" +msgstr " output:\n" + +#: main.c:157 main.c:230 +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL " +"per disabilitarlo.\n" + +#: main.c:159 +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Modalità sicura in esecuzione! Auto-reload disattivato.\n" + +#: main.c:161 main.c:232 +msgid "Auto-reload is off.\n" +msgstr "Auto-reload disattivato.\n" + +#: main.c:175 +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" + +#: main.c:191 +msgid "WARNING: Your code filename has two extensions\n" +msgstr "ATTENZIONE: Il nome del sorgente ha due estensioni\n" + +#: main.c:239 +msgid "You requested starting safe mode by " +msgstr "È stato richiesto l'avvio in modalità sicura da " + +#: main.c:242 +msgid "To exit, please reset the board without " +msgstr "Per uscire resettare la scheda senza " + +#: main.c:249 +msgid "" +"You are running in safe mode which means something really bad happened.\n" +msgstr "" +"Sei nella modalità sicura che significa che qualcosa di molto brutto è " +"successo.\n" + +#: main.c:251 +msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" +msgstr "" +"Sembra che il codice del core di CircuitPython sia crashato malamente. " +"Whoops!\n" + +#: main.c:252 +msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" +msgstr "" +"Ti preghiamo di compilare una issue con il contenuto del tuo drie " +"CIRCUITPY:\n" + +#: main.c:255 +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +msgstr "" +"La potenza del microcontrollore è calata. Assicurati che l'alimentazione sia " +"attaccata correttamente\n" + +#: main.c:256 +msgid "" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"abbastanza potenza per l'intero circuito e premere reset (dopo aver espulso " +"CIRCUITPY).\n" + +#: main.c:260 +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Premi un qualunque tasto per entrare nel REPL. Usa CTRL-D per ricaricare." + +#: main.c:416 +msgid "soft reboot\n" +msgstr "soft reboot\n" + +#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 +msgid "All sync event channels in use" +msgstr "Tutti i canali di eventi sincronizzati in uso" + +#: ports/atmel-samd/bindings/samd/Clock.c:135 +msgid "calibration is read only" +msgstr "la calibrazione è in sola lettura" + +#: ports/atmel-samd/bindings/samd/Clock.c:137 +msgid "calibration is out of range" +msgstr "la calibrazione è fuori intervallo" + +#: ports/atmel-samd/board_busses.c:59 ports/nrf/board_busses.c:39 +msgid "No default I2C bus" +msgstr "Nessun bus I2C predefinito" + +#: ports/atmel-samd/board_busses.c:85 ports/nrf/board_busses.c:64 +msgid "No default SPI bus" +msgstr "Nessun bus SPI predefinito" + +#: ports/atmel-samd/board_busses.c:112 ports/nrf/board_busses.c:91 +msgid "No default UART bus" +msgstr "Nessun bus UART predefinito" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 +#: ports/nrf/common-hal/analogio/AnalogIn.c:39 +msgid "Pin does not have ADC capabilities" +msgstr "Il pin non ha capacità di ADC" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 +msgid "No DAC on chip" +msgstr "Nessun DAC sul chip" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c:56 +msgid "AnalogOut not supported on given pin" +msgstr "AnalogOut non supportato sul pin scelto" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 +msgid "Invalid bit clock pin" +msgstr "Pin del clock di bit non valido" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 +msgid "Bit clock and word select must share a clock unit" +msgstr "" +"Clock di bit e selezione parola devono condividere la stessa unità di clock" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 +msgid "Invalid data pin" +msgstr "Pin dati non valido" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:169 +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:174 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 +msgid "Serializer in use" +msgstr "Serializer in uso" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 +msgid "Clock unit in use" +msgstr "Unità di clock in uso" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 +msgid "Unable to find free GCLK" +msgstr "Impossibile trovare un GCLK libero" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 +msgid "Too many channels in sample." +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +msgid "No DMA channel found" +msgstr "Nessun canale DMA trovato" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +msgid "Unable to allocate buffers for signed conversion" +msgstr "Ipossibilitato ad allocare buffer per la conversione con segno" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:109 +msgid "Invalid clock pin" +msgstr "Pin di clock non valido" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 +msgid "sampling rate out of range" +msgstr "frequenza di campionamento fuori intervallo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +msgid "DAC already in use" +msgstr "DAC già in uso" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +msgid "Right channel unsupported" +msgstr "Canale destro non supportato" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 +msgid "Invalid pin" +msgstr "Pin non valido" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +msgid "Invalid pin for left channel" +msgstr "Pin non valido per il canale sinistro" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +msgid "Invalid pin for right channel" +msgstr "Pin non valido per il canale destro" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +msgid "Cannot output both channels on the same pin" +msgstr "Impossibile dare in output entrambi i canal sullo stesso pin" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +msgid "All timers in use" +msgstr "Tutti i timer utilizzati" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +msgid "All event channels in use" +msgstr "Tutti i canali eventi utilizati" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" +"Frequenza di campionamento troppo alta. Il valore deve essere inferiore a %d" + +#: ports/atmel-samd/common-hal/busio/I2C.c:71 +msgid "Not enough pins available" +msgstr "Non sono presenti abbastanza pin" + +#: ports/atmel-samd/common-hal/busio/I2C.c:78 +#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/UART.c:119 +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 +#: ports/nrf/common-hal/busio/I2C.c:81 +msgid "Invalid pins" +msgstr "Pin non validi" + +#: ports/atmel-samd/common-hal/busio/I2C.c:101 +msgid "SDA or SCL needs a pull up" +msgstr "SDA o SCL necessitano un pull-up" + +#: ports/atmel-samd/common-hal/busio/I2C.c:121 +msgid "Unsupported baudrate" +msgstr "baudrate non supportato" + +#: ports/atmel-samd/common-hal/busio/UART.c:66 +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit non supportati" + +#: ports/atmel-samd/common-hal/busio/UART.c:72 +#: ports/nrf/common-hal/busio/UART.c:82 +msgid "tx and rx cannot both be None" +msgstr "tx e rx non possono essere entrambi None" + +#: ports/atmel-samd/common-hal/busio/UART.c:145 +#: ports/nrf/common-hal/busio/UART.c:115 +msgid "Failed to allocate RX buffer" +msgstr "Impossibile allocare buffer RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:153 +msgid "Could not initialize UART" +msgstr "Impossibile inizializzare l'UART" + +#: ports/atmel-samd/common-hal/busio/UART.c:240 +#: ports/nrf/common-hal/busio/UART.c:149 +msgid "No RX pin" +msgstr "Nessun pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c:294 +#: ports/nrf/common-hal/busio/UART.c:195 +msgid "No TX pin" +msgstr "Nessun pin TX" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 +#: ports/esp8266/common-hal/microcontroller/__init__.c:64 +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" +"Impossibile resettare nel bootloader poiché nessun bootloader è presente." + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 +#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +msgid "Invalid PWM frequency" +msgstr "Frequenza PWM non valida" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c:187 +msgid "All timers for this pin are in use" +msgstr "Tutti i timer per questo pin sono in uso" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 +msgid "No hardware support on pin" +msgstr "Nessun supporto hardware sul pin" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 +msgid "EXTINT channel already in use" +msgstr "Canale EXTINT già in uso" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:118 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:86 +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Fallita allocazione del buffer RX di %d byte" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:151 +msgid "pop from an empty PulseIn" +msgstr "pop sun un PulseIn vuoto" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 +#: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 +msgid "index out of range" +msgstr "indice fuori intervallo" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c:178 +msgid "Another send is already active" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:38 +msgid "Both pins must support hardware interrupts" +msgstr "Entrambi i pin devono supportare gli interrupt hardware" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c:46 +msgid "A hardware interrupt channel is already in use" +msgstr "Un canale di interrupt hardware è già in uso" + +#: ports/atmel-samd/common-hal/rtc/RTC.c:101 +msgid "calibration value out of range +/-127" +msgstr "valore di calibrazione fuori intervallo +/-127" + +#: ports/atmel-samd/common-hal/storage/__init__.c:48 +msgid "Cannot remount '/' when USB is active." +msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 +msgid "No free GCLKs" +msgstr "Nessun GCLK libero" + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 +#: ports/nrf/common-hal/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 +#: ports/nrf/common-hal/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB occupata" + +#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 +#: ports/nrf/common-hal/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "Errore USB" + +#: ports/esp8266/common-hal/analogio/AnalogIn.c:43 +msgid "Pin %q does not have ADC capabilities" +msgstr "Il pin %q non ha capacità ADC" + +#: ports/esp8266/common-hal/analogio/AnalogOut.c:39 +msgid "No hardware support for analog out." +msgstr "Nessun supporto hardware per l'uscita analogica." + +#: ports/esp8266/common-hal/busio/SPI.c:72 +msgid "Pins not valid for SPI" +msgstr "Pin non validi per SPI" + +#: ports/esp8266/common-hal/busio/UART.c:45 +msgid "Only tx supported on UART1 (GPIO2)." +msgstr "Solo tx supportato su UART1 (GPIO2)." + +#: ports/esp8266/common-hal/busio/UART.c:67 ports/esp8266/machine_uart.c:108 +msgid "invalid data bits" +msgstr "bit dati invalidi" + +#: ports/esp8266/common-hal/busio/UART.c:91 ports/esp8266/machine_uart.c:144 +msgid "invalid stop bits" +msgstr "bit di stop invalidi" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 +msgid "ESP8266 does not support pull down." +msgstr "ESP8266 non supporta pull-down" + +#: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 +msgid "GPIO16 does not support pull up." +msgstr "GPIO16 non supporta pull-up" + +#: ports/esp8266/common-hal/microcontroller/__init__.c:66 +msgid "ESP8226 does not support safe mode." +msgstr "ESP8266 non supporta la modalità sicura." + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:54 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:113 +#, c-format +msgid "Maximum PWM frequency is %dhz." +msgstr "Frequenza massima su PWM è %dhz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:57 +#: ports/esp8266/common-hal/pulseio/PWMOut.c:116 +msgid "Minimum PWM frequency is 1hz." +msgstr "Frequenza minima su PWM è 1hz" + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:68 +#, c-format +msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +msgstr "Frequenze PWM multiple non supportate. PWM già impostato a %shz." + +#: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 +#, c-format +msgid "PWM not supported on pin %d" +msgstr "PWM non è supportato sul pin %d" + +#: ports/esp8266/common-hal/pulseio/PulseIn.c:78 +msgid "No PulseIn support for %q" +msgstr "Nessun supporto per PulseIn per %q" + +#: ports/esp8266/common-hal/storage/__init__.c:34 +msgid "Unable to remount filesystem" +msgstr "Imposssibile rimontare il filesystem" + +#: ports/esp8266/common-hal/storage/__init__.c:38 +msgid "Use esptool to erase flash and re-upload Python instead" +msgstr "Usa esptool per cancellare la flash e ricaricare Python invece" + +#: ports/esp8266/esp_mphal.c:154 +msgid "C-level assert" +msgstr "assert a livello C" + +#: ports/esp8266/machine_adc.c:57 +#, c-format +msgid "not a valid ADC Channel: %d" +msgstr "canale ADC non valido: %d" + +#: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 +msgid "impossible baudrate" +msgstr "baudrate impossibile" + +#: ports/esp8266/machine_pin.c:129 +msgid "expecting a pin" +msgstr "pin atteso" + +#: ports/esp8266/machine_pin.c:284 +msgid "Pin(16) doesn't support pull" +msgstr "Pin(16) non supporta pull" + +#: ports/esp8266/machine_pin.c:323 +msgid "invalid pin" +msgstr "pin non valido" + +#: ports/esp8266/machine_pin.c:389 +msgid "pin does not have IRQ capabilities" +msgstr "il pin non implementa IRQ" + +#: ports/esp8266/machine_rtc.c:185 +msgid "buffer too long" +msgstr "buffer troppo lungo" + +#: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 +#: ports/esp8266/machine_rtc.c:246 +msgid "invalid alarm" +msgstr "alarm non valido" + +#: ports/esp8266/machine_uart.c:169 +#, c-format +msgid "UART(%d) does not exist" +msgstr "UART(%d) non esistente" + +#: ports/esp8266/machine_uart.c:219 +msgid "UART(1) can't read" +msgstr "UART(1) non leggibile" + +#: ports/esp8266/modesp.c:119 +msgid "len must be multiple of 4" +msgstr "len deve essere multiplo di 4" + +#: ports/esp8266/modesp.c:274 +#, c-format +msgid "memory allocation failed, allocating %u bytes for native code" +msgstr "" +"allocazione di memoria fallita, allocazione di %d byte per codice nativo" + +#: ports/esp8266/modesp.c:317 +msgid "flash location must be below 1MByte" +msgstr "Locazione della flash deve essere inferiore a 1mb" + +#: ports/esp8266/modmachine.c:63 +msgid "frequency can only be either 80Mhz or 160MHz" +msgstr "la frequenza può essere o 80Mhz o 160Mhz" + +#: ports/esp8266/modnetwork.c:61 +msgid "AP required" +msgstr "AP richiesto" + +#: ports/esp8266/modnetwork.c:61 +msgid "STA required" +msgstr "STA richiesta" + +#: ports/esp8266/modnetwork.c:87 +msgid "Cannot update i/f status" +msgstr "Impossibile aggiornare status di i/f" + +#: ports/esp8266/modnetwork.c:142 +msgid "Cannot set STA config" +msgstr "Impossibile impostare la configurazione della STA" + +#: ports/esp8266/modnetwork.c:144 +msgid "Cannot connect to AP" +msgstr "Impossible connettersi all'AP" + +#: ports/esp8266/modnetwork.c:152 +msgid "Cannot disconnect from AP" +msgstr "Impossible disconnettersi all'AP" + +#: ports/esp8266/modnetwork.c:173 +msgid "unknown status param" +msgstr "prametro di stato sconosciuto" + +#: ports/esp8266/modnetwork.c:222 +msgid "STA must be active" +msgstr "STA deve essere attiva" + +#: ports/esp8266/modnetwork.c:239 +msgid "scan failed" +msgstr "scansione fallita" + +#: ports/esp8266/modnetwork.c:306 +msgid "wifi_set_ip_info() failed" +msgstr "wifi_set_ip_info() faillito" + +#: ports/esp8266/modnetwork.c:319 +msgid "either pos or kw args are allowed" +msgstr "sono permesse solo gli argomenti pos o kw" + +#: ports/esp8266/modnetwork.c:329 +msgid "can't get STA config" +msgstr "impossibile recuperare la configurazione della STA" + +#: ports/esp8266/modnetwork.c:331 +msgid "can't get AP config" +msgstr "impossibile recuperare le configurazioni dell'AP" + +#: ports/esp8266/modnetwork.c:346 +msgid "invalid buffer length" +msgstr "lunghezza del buffer non valida" + +#: ports/esp8266/modnetwork.c:405 +msgid "can't set STA config" +msgstr "impossibile impostare le configurazioni della STA" + +#: ports/esp8266/modnetwork.c:407 +msgid "can't set AP config" +msgstr "impossibile impostare le configurazioni dell'AP" + +#: ports/esp8266/modnetwork.c:416 +msgid "can query only one param" +msgstr "è possibile interrogare solo un parametro" + +#: ports/esp8266/modnetwork.c:469 +msgid "unknown config param" +msgstr "parametro di configurazione sconosciuto" + +#: ports/nrf/common-hal/analogio/AnalogOut.c:37 +msgid "AnalogOut functionality not supported" +msgstr "funzionalità AnalogOut non supportata" + +#: ports/nrf/common-hal/busio/I2C.c:95 +msgid "All I2C peripherals are in use" +msgstr "Tutte le periferiche I2C sono in uso" + +#: ports/nrf/common-hal/busio/SPI.c:115 +msgid "All SPI peripherals are in use" +msgstr "Tutte le periferiche SPI sono in uso" + +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "lunghezza del buffer non valida" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "operazione I2C non supportata" + +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +#, fuzzy +msgid "busio.UART not available" +msgstr "busio.UART non ancora implementato" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "Impossibile leggere la temperatura. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:199 +msgid "Cannot apply GAP parameters." +msgstr "Impossibile applicare i parametri GAP." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:213 +msgid "Cannot set PPCP parameters." +msgstr "Impossibile impostare i parametri PPCP." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:245 +msgid "Can not query for the device address." +msgstr "Non è possibile trovare l'indirizzo del dispositivo." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:264 +msgid "Can not add Vendor Specific 128-bit UUID." +msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:284 +#: ports/nrf/drivers/bluetooth/ble_drv.c:298 +msgid "Can not add Service." +msgstr "Non è possibile aggiungere Service." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:373 +msgid "Can not add Characteristic." +msgstr "Non è possibile aggiungere Characteristic." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:400 +msgid "Can not apply device name in the stack." +msgstr "Non è possibile inserire il nome del dipositivo nella lista." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:464 +#: ports/nrf/drivers/bluetooth/ble_drv.c:514 +msgid "Can not encode UUID, to check length." +msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:470 +#: ports/nrf/drivers/bluetooth/ble_drv.c:520 +msgid "Can encode UUID into the advertisement packet." +msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:545 +msgid "Can not fit data into the advertisement packet." +msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#: ports/nrf/drivers/bluetooth/ble_drv.c:558 +#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#, c-format +msgid "Can not apply advertisement data. status: 0x%02x" +msgstr "Impossible inserire dati advertisement. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#, c-format +msgid "Can not start advertisement. status: 0x%02x" +msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#, c-format +msgid "Can not stop advertisement. status: 0x%02x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:650 +#: ports/nrf/drivers/bluetooth/ble_drv.c:726 +#, c-format +msgid "Can not read attribute value. status: 0x%02x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:667 +#: ports/nrf/drivers/bluetooth/ble_drv.c:756 +#, c-format +msgid "Can not write attribute value. status: 0x%02x" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:691 +#, c-format +msgid "Can not notify attribute value. status: 0x%02x" +msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:784 +#, c-format +msgid "Can not start scanning. status: 0x%02x" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#, c-format +msgid "Can not connect. status: 0x%02x" +msgstr "Impossibile connettersi. status: 0x%02x" + +#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 +#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 +#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 +#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 +msgid "Invalid UUID parameter" +msgstr "Parametro UUID non valido" + +#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 +msgid "Invalid Service type" +msgstr "Tipo di servizio non valido" + +#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 +msgid "Invalid UUID string length" +msgstr "Lunghezza della stringa UUID non valida" + +#: ports/unix/modffi.c:138 +msgid "Unknown type" +msgstr "Tipo sconosciuto" + +#: ports/unix/modffi.c:207 ports/unix/modffi.c:265 +msgid "Error in ffi_prep_cif" +msgstr "Errore in ffi_prep_cif" + +#: ports/unix/modffi.c:270 +msgid "ffi_prep_closure_loc" +msgstr "ffi_prep_closure_loc" + +#: ports/unix/modffi.c:413 +msgid "Don't know how to pass object to native function" +msgstr "Non so come passare l'oggetto alla funzione nativa" + +#: ports/unix/modusocket.c:474 +#, c-format +msgid "[addrinfo error %d]" +msgstr "[errore addrinfo %d]" + +#: py/argcheck.c:44 +msgid "function does not take keyword arguments" +msgstr "la funzione non prende argomenti nominati" + +#: py/argcheck.c:54 py/bc.c:85 py/objnamedtuple.c:104 +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" +"la funzione prende %d argomenti posizionali ma ne sono stati forniti %d" + +#: py/argcheck.c:64 +#, c-format +msgid "function missing %d required positional arguments" +msgstr "mancano %d argomenti posizionali obbligatori alla funzione" + +#: py/argcheck.c:72 +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "la funzione prevede al massimo %d argmoneti, ma ne ha ricevuti %d" + +#: py/argcheck.c:97 +msgid "'%q' argument required" +msgstr "'%q' argomento richiesto" + +#: py/argcheck.c:122 +msgid "extra positional arguments given" +msgstr "argomenti posizonali extra dati" + +#: py/argcheck.c:130 +msgid "extra keyword arguments given" +msgstr "argomento nominato aggiuntivo fornito" + +#: py/argcheck.c:142 +msgid "argument num/types mismatch" +msgstr "discrepanza di numero/tipo di argomenti" + +#: py/argcheck.c:147 +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"argomento(i) nominati non ancora implementati - usare invece argomenti " +"normali" + +#: py/bc.c:88 py/objnamedtuple.c:108 +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" + +#: py/bc.c:197 py/bc.c:215 +msgid "unexpected keyword argument" +msgstr "argomento nominato inaspettato" + +#: py/bc.c:199 +msgid "keywords must be strings" +msgstr "argomenti nominati devono essere stringhe" + +#: py/bc.c:206 py/objnamedtuple.c:138 +msgid "function got multiple values for argument '%q'" +msgstr "la funzione ha ricevuto valori multipli per l'argomento '%q'" + +#: py/bc.c:218 py/objnamedtuple.c:130 +msgid "unexpected keyword argument '%q'" +msgstr "argomento nominato '%q' inaspettato" + +#: py/bc.c:244 +#, c-format +msgid "function missing required positional argument #%d" +msgstr "mancante il #%d argomento posizonale obbligatorio della funzione" + +#: py/bc.c:260 +msgid "function missing required keyword argument '%q'" +msgstr "argomento nominato '%q' mancante alla funzione" + +#: py/bc.c:269 +msgid "function missing keyword-only argument" +msgstr "argomento nominato mancante alla funzione" + +#: py/binary.c:112 +msgid "bad typecode" +msgstr "" + +#: py/builtinevex.c:99 +msgid "bad compile mode" +msgstr "" + +#: py/builtinimport.c:338 +msgid "cannot perform relative import" +msgstr "impossibile effettuare l'importazione relativa" + +#: py/builtinimport.c:422 py/builtinimport.c:534 +msgid "module not found" +msgstr "modulo non trovato" + +#: py/builtinimport.c:425 py/builtinimport.c:537 +msgid "no module named '%q'" +msgstr "nessun modulo chiamato '%q'" + +#: py/builtinimport.c:512 +msgid "relative import" +msgstr "importazione relativa" + +#: py/compile.c:397 py/compile.c:542 +msgid "can't assign to expression" +msgstr "impossibile assegnare all'espressione" + +#: py/compile.c:416 +msgid "multiple *x in assignment" +msgstr "*x multipli nell'assegnamento" + +#: py/compile.c:642 +msgid "non-default argument follows default argument" +msgstr "argomento non predefinito segue argmoento predfinito" + +#: py/compile.c:771 py/compile.c:789 +msgid "invalid micropython decorator" +msgstr "decoratore non valido in micropython" + +#: py/compile.c:943 +msgid "can't delete expression" +msgstr "impossibile cancellare l'espessione" + +#: py/compile.c:955 +msgid "'break' outside loop" +msgstr "'break' al di fuori del ciclo" + +#: py/compile.c:958 +msgid "'continue' outside loop" +msgstr "'continue' al di fuori del ciclo" + +#: py/compile.c:969 +msgid "'return' outside function" +msgstr "'return' al di fuori della funzione" + +#: py/compile.c:1169 +msgid "identifier redefined as global" +msgstr "identificatore ridefinito come globale" + +#: py/compile.c:1185 +msgid "no binding for nonlocal found" +msgstr "nessun binding per nonlocal trovato" + +#: py/compile.c:1188 +msgid "identifier redefined as nonlocal" +msgstr "identificatore ridefinito come nonlocal" + +#: py/compile.c:1197 +msgid "can't declare nonlocal in outer code" +msgstr "impossibile dichiarare nonlocal nel codice esterno" + +#: py/compile.c:1542 +msgid "default 'except' must be last" +msgstr "'except' predefinito deve essere ultimo" + +#: py/compile.c:2095 +msgid "*x must be assignment target" +msgstr "" + +#: py/compile.c:2193 +msgid "super() can't find self" +msgstr "" + +#: py/compile.c:2256 +msgid "can't have multiple *x" +msgstr "impossibile usare *x multipli" + +#: py/compile.c:2263 +msgid "can't have multiple **x" +msgstr "impossibile usare **x multipli" + +#: py/compile.c:2271 +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: py/compile.c:2287 +msgid "non-keyword arg after */**" +msgstr "argomento non nominato dopo */**" + +#: py/compile.c:2291 +msgid "non-keyword arg after keyword arg" +msgstr "argomento non nominato seguito da argomento nominato" + +#: py/compile.c:2463 py/compile.c:2473 py/compile.c:2712 py/compile.c:2742 +#: py/parse.c:1176 +msgid "invalid syntax" +msgstr "sintassi non valida" + +#: py/compile.c:2465 +msgid "expecting key:value for dict" +msgstr "chiave:valore atteso per dict" + +#: py/compile.c:2475 +msgid "expecting just a value for set" +msgstr "un solo valore atteso per set" + +#: py/compile.c:2600 +msgid "'yield' outside function" +msgstr "'yield' al di fuori della funzione" + +#: py/compile.c:2619 +msgid "'await' outside function" +msgstr "'await' al di fuori della funzione" + +#: py/compile.c:2774 +msgid "name reused for argument" +msgstr "nome riutilizzato come argomento" + +#: py/compile.c:2827 +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/compile.c:2969 py/compile.c:3137 +msgid "return annotation must be an identifier" +msgstr "" + +#: py/compile.c:3097 +msgid "inline assembler must be a function" +msgstr "inline assembler deve essere una funzione" + +#: py/compile.c:3134 +msgid "unknown type" +msgstr "tipo sconosciuto" + +#: py/compile.c:3154 +msgid "expecting an assembler instruction" +msgstr "istruzione assembler attesa" + +#: py/compile.c:3184 +msgid "'label' requires 1 argument" +msgstr "'label' richiede 1 argomento" + +#: py/compile.c:3190 +msgid "label redefined" +msgstr "etichetta ridefinita" + +#: py/compile.c:3196 +msgid "'align' requires 1 argument" +msgstr "'align' richiede 1 argomento" + +#: py/compile.c:3205 +msgid "'data' requires at least 2 arguments" +msgstr "'data' richiede almeno 2 argomento" + +#: py/compile.c:3212 +msgid "'data' requires integer arguments" +msgstr "'data' richiede argomenti interi" + +#: py/emitinlinethumb.c:102 +#, fuzzy +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" + +#: py/emitinlinethumb.c:107 py/emitinlinethumb.c:112 +#, fuzzy +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parametri devono essere i registri in sequenza da a2 a a5" + +#: py/emitinlinethumb.c:188 py/emitinlinethumb.c:230 +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:197 py/emitinlinextensa.c:162 +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:211 +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:239 +#, fuzzy, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:292 +#, fuzzy, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:299 py/emitinlinextensa.c:169 +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' aspetta un intero" + +#: py/emitinlinethumb.c:304 +#, fuzzy, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "intero '%s' non è nell'intervallo %d..%d" + +#: py/emitinlinethumb.c:328 +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c:334 py/emitinlinextensa.c:182 +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' aspetta una etichetta" + +#: py/emitinlinethumb.c:345 py/emitinlinextensa.c:193 +msgid "label '%q' not defined" +msgstr "etichetta '%q' non definita" + +#: py/emitinlinethumb.c:806 +#, fuzzy, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "istruzione '%s' Xtensa non supportata con %d argomenti" + +#: py/emitinlinethumb.c:810 +#, fuzzy +msgid "branch not in range" +msgstr "argomento di chr() non è in range(256)" + +#: py/emitinlinextensa.c:86 +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" + +#: py/emitinlinextensa.c:91 py/emitinlinextensa.c:96 +msgid "parameters must be registers in sequence a2 to a5" +msgstr "parametri devono essere i registri in sequenza da a2 a a5" + +#: py/emitinlinextensa.c:174 +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "intero '%s' non è nell'intervallo %d..%d" + +#: py/emitinlinextensa.c:327 +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "istruzione '%s' Xtensa non supportata con %d argomenti" + +#: py/emitnative.c:183 +msgid "unknown type '%q'" +msgstr "tipo '%q' sconosciuto" + +#: py/emitnative.c:260 +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" + +#: py/emitnative.c:742 +msgid "conversion to object" +msgstr "conversione in oggetto" + +#: py/emitnative.c:921 +msgid "local '%q' used before type known" +msgstr "locla '%q' utilizzato prima che il tipo fosse noto" + +#: py/emitnative.c:1118 py/emitnative.c:1156 +msgid "can't load from '%q'" +msgstr "impossibile caricare da '%q'" + +#: py/emitnative.c:1128 +msgid "can't load with '%q' index" +msgstr "impossibile caricare con indice '%q'" + +#: py/emitnative.c:1188 +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "local '%q' ha tipo '%q' ma sorgente è '%q'" + +#: py/emitnative.c:1289 py/emitnative.c:1379 +msgid "can't store '%q'" +msgstr "impossibile memorizzare '%q'" + +#: py/emitnative.c:1358 py/emitnative.c:1419 +msgid "can't store to '%q'" +msgstr "impossibile memorizzare in '%q'" + +#: py/emitnative.c:1369 +msgid "can't store with '%q' index" +msgstr "impossibile memorizzare con indice '%q'" + +#: py/emitnative.c:1540 +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "non è possibile convertire implicitamente '%q' in 'bool'" + +#: py/emitnative.c:1774 +msgid "unary op %q not implemented" +msgstr "operazione unaria %q non implementata" + +#: py/emitnative.c:1930 +msgid "binary op %q not implemented" +msgstr "operazione binaria %q non implementata" + +#: py/emitnative.c:1951 +msgid "can't do binary op between '%q' and '%q'" +msgstr "impossibile eseguire operazione binaria tra '%q' e '%q'" + +#: py/emitnative.c:2126 +msgid "casting" +msgstr "casting" + +#: py/emitnative.c:2173 +msgid "return expected '%q' but got '%q'" +msgstr "return aspettava '%q' ma ha ottenuto '%q'" + +#: py/emitnative.c:2191 +msgid "must raise an object" +msgstr "deve lanciare un oggetto" + +#: py/emitnative.c:2201 +msgid "native yield" +msgstr "yield nativo" + +#: py/lexer.c:345 +msgid "unicode name escapes" +msgstr "" + +#: py/modbuiltins.c:162 +msgid "chr() arg not in range(0x110000)" +msgstr "argomento di chr() non è in range(0x110000)" + +#: py/modbuiltins.c:171 +msgid "chr() arg not in range(256)" +msgstr "argomento di chr() non è in range(256)" + +#: py/modbuiltins.c:285 +msgid "arg is an empty sequence" +msgstr "l'argomento è una sequenza vuota" + +#: py/modbuiltins.c:350 +msgid "ord expects a character" +msgstr "ord() aspetta un carattere" + +#: py/modbuiltins.c:353 +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" +"ord() aspettava un carattere, ma ha ricevuto una stringa di lunghezza %d" + +#: py/modbuiltins.c:363 +msgid "3-arg pow() not supported" +msgstr "pow() con tre argmomenti non supportata" + +#: py/modbuiltins.c:517 +msgid "must use keyword argument for key function" +msgstr "" + +#: py/modmath.c:41 shared-bindings/math/__init__.c:53 +msgid "math domain error" +msgstr "errore di dominio matematico" + +#: py/modmath.c:196 py/objfloat.c:270 py/objint_longlong.c:222 +#: py/objint_mpz.c:230 py/runtime.c:619 shared-bindings/math/__init__.c:346 +msgid "division by zero" +msgstr "divisione per zero" + +#: py/modmicropython.c:155 +msgid "schedule stack full" +msgstr "" + +#: py/modstruct.c:145 py/modstruct.c:153 py/modstruct.c:234 py/modstruct.c:244 +#: shared-bindings/struct/__init__.c:103 shared-bindings/struct/__init__.c:145 +#: shared-module/struct/__init__.c:91 shared-module/struct/__init__.c:175 +msgid "buffer too small" +msgstr "buffer troppo piccolo" + +#: py/modthread.c:240 +msgid "expecting a dict for keyword args" +msgstr "argomenti nominati necessitano un dizionario" + +#: py/moduerrno.c:143 py/moduerrno.c:146 +msgid "Permission denied" +msgstr "Permesso negato" + +#: py/moduerrno.c:144 +msgid "No such file/directory" +msgstr "Nessun file/directory esistente" + +#: py/moduerrno.c:145 +msgid "Input/output error" +msgstr "Errore input/output" + +#: py/moduerrno.c:147 +msgid "File exists" +msgstr "File esistente" + +#: py/moduerrno.c:148 +msgid "Unsupported operation" +msgstr "Operazione non supportata" + +#: py/moduerrno.c:149 +msgid "Invalid argument" +msgstr "Argomento non valido" + +#: py/obj.c:90 +msgid "Traceback (most recent call last):\n" +msgstr "Traceback (chiamata più recente per ultima):\n" + +#: py/obj.c:94 +msgid " File \"%q\", line %d" +msgstr " File \"%q\", riga %d" + +#: py/obj.c:96 +msgid " File \"%q\"" +msgstr " File \"%q\"" + +#: py/obj.c:100 +msgid ", in %q\n" +msgstr ", in %q\n" + +#: py/obj.c:257 +msgid "can't convert to int" +msgstr "non è possibile convertire a int" + +#: py/obj.c:260 +#, c-format +msgid "can't convert %s to int" +msgstr "non è possibile convertire %s a int" + +#: py/obj.c:320 +msgid "can't convert to float" +msgstr "non è possibile convertire a float" + +#: py/obj.c:323 +#, c-format +msgid "can't convert %s to float" +msgstr "non è possibile convertire %s a float" + +#: py/obj.c:353 +msgid "can't convert to complex" +msgstr "non è possibile convertire a complex" + +#: py/obj.c:356 +#, c-format +msgid "can't convert %s to complex" +msgstr "non è possibile convertire a complex" + +#: py/obj.c:371 +msgid "expected tuple/list" +msgstr "lista/tupla prevista" + +#: py/obj.c:374 +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "oggetto '%s' non è una tupla o una lista" + +#: py/obj.c:385 +msgid "tuple/list has wrong length" +msgstr "tupla/lista ha la lunghezza sbagliata" + +#: py/obj.c:387 +#, c-format +msgid "requested length %d but object has length %d" +msgstr "lunghezza %d richiesta ma l'oggetto ha lunghezza %d" + +#: py/obj.c:400 +msgid "indices must be integers" +msgstr "gli indici devono essere interi" + +#: py/obj.c:403 +msgid "%q indices must be integers, not %s" +msgstr "gli indici %q devono essere interi, non %s" + +#: py/obj.c:423 +msgid "%q index out of range" +msgstr "indice %q fuori intervallo" + +#: py/obj.c:455 +msgid "object has no len" +msgstr "l'oggetto non ha lunghezza" + +#: py/obj.c:458 +#, c-format +msgid "object of type '%s' has no len()" +msgstr "l'oggetto di tipo '%s' non implementa len()" + +#: py/obj.c:496 +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c:499 +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/obj.c:503 +msgid "object is not subscriptable" +msgstr "" + +#: py/obj.c:506 +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/obj.c:510 +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c:513 +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c:544 +msgid "object with buffer protocol required" +msgstr "" + +#: py/objarray.c:413 py/objstr.c:427 py/objstrunicode.c:191 py/objtuple.c:187 +#: shared-bindings/nvm/ByteArray.c:85 +msgid "only slices with step=1 (aka None) are supported" +msgstr "solo slice con step=1 (aka None) sono supportate" + +#: py/objarray.c:426 +msgid "lhs and rhs should be compatible" +msgstr "lhs e rhs devono essere compatibili" + +#: py/objarray.c:444 shared-bindings/nvm/ByteArray.c:107 +msgid "array/bytes required on right side" +msgstr "" + +#: py/objcomplex.c:203 +msgid "can't do truncated division of a complex number" +msgstr "impossibile fare il modulo di un numero complesso" + +#: py/objcomplex.c:209 +msgid "complex division by zero" +msgstr "complex divisione per zero" + +#: py/objcomplex.c:237 +msgid "0.0 to a complex power" +msgstr "0.0 elevato alla potenza di un numero complesso" + +#: py/objdeque.c:107 +msgid "full" +msgstr "pieno" + +#: py/objdeque.c:127 +msgid "empty" +msgstr "vuoto" + +#: py/objdict.c:314 +msgid "popitem(): dictionary is empty" +msgstr "popitem(): il dizionario è vuoto" + +#: py/objdict.c:357 +msgid "dict update sequence has wrong length" +msgstr "sequanza di aggiornamento del dizionario ha la lunghezza errata" + +#: py/objfloat.c:308 py/parsenum.c:331 +msgid "complex values not supported" +msgstr "valori complessi non supportai" + +#: py/objgenerator.c:108 +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objgenerator.c:126 +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c:229 +msgid "generator ignored GeneratorExit" +msgstr "" + +#: py/objgenerator.c:251 +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objint.c:144 +msgid "can't convert inf to int" +msgstr "impossibile convertire inf in int" + +#: py/objint.c:146 +msgid "can't convert NaN to int" +msgstr "impossibile convertire NaN in int" + +#: py/objint.c:163 +msgid "float too big" +msgstr "float troppo grande" + +#: py/objint.c:328 +msgid "long int not supported in this build" +msgstr "long int non supportata in questa build" + +#: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 +msgid "small int overflow" +msgstr "small int overflow" + +#: py/objint_longlong.c:189 py/objint_mpz.c:283 py/runtime.c:486 +msgid "negative power with no float support" +msgstr "potenza negativa senza supporto per float" + +#: py/objint_longlong.c:251 +msgid "ulonglong too large" +msgstr "ulonglong troppo grande" + +#: py/objint_mpz.c:267 py/runtime.c:396 py/runtime.c:411 +msgid "negative shift count" +msgstr "" + +#: py/objint_mpz.c:336 +msgid "pow() with 3 arguments requires integers" +msgstr "pow() con 3 argomenti richiede interi" + +#: py/objint_mpz.c:347 +msgid "pow() 3rd argument cannot be 0" +msgstr "il terzo argomento di pow() non può essere 0" + +#: py/objint_mpz.c:415 +msgid "overflow converting long int to machine word" +msgstr "overflow convertendo long int in parola" + +#: py/objlist.c:273 +msgid "pop from empty list" +msgstr "pop da una lista vuota" + +#: py/objnamedtuple.c:92 +msgid "can't set attribute" +msgstr "impossibile impostare attributo" + +#: py/objobject.c:55 +msgid "__new__ arg must be a user-type" +msgstr "" + +#: py/objrange.c:110 +msgid "zero step" +msgstr "zero step" + +#: py/objset.c:371 +msgid "pop from an empty set" +msgstr "pop da un set vuoto" + +#: py/objslice.c:66 +msgid "Length must be an int" +msgstr "Length deve essere un intero" + +#: py/objslice.c:71 +msgid "Length must be non-negative" +msgstr "Length deve essere non negativo" + +#: py/objslice.c:86 py/sequence.c:57 +msgid "slice step cannot be zero" +msgstr "la step della slice non può essere zero" + +#: py/objslice.c:159 +msgid "Cannot subclass slice" +msgstr "Impossibile subclasare slice" + +#: py/objstr.c:261 +msgid "bytes value out of range" +msgstr "valore byte fuori intervallo" + +#: py/objstr.c:270 +msgid "wrong number of arguments" +msgstr "numero di argomenti errato" + +#: py/objstr.c:467 +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"join prende una lista di oggetti str/byte consistenti con l'oggetto stesso" + +#: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 +msgid "empty separator" +msgstr "separatore vuoto" + +#: py/objstr.c:641 +msgid "rsplit(None,n)" +msgstr "" + +#: py/objstr.c:713 +msgid "substring not found" +msgstr "sottostringa non trovata" + +#: py/objstr.c:770 +msgid "start/end indices" +msgstr "" + +#: py/objstr.c:931 +msgid "bad format string" +msgstr "stringa di formattazione scorretta" + +#: py/objstr.c:953 +msgid "single '}' encountered in format string" +msgstr "'}' singolo presente nella stringa di formattazione" + +#: py/objstr.c:992 +msgid "bad conversion specifier" +msgstr "specificatore di conversione scorretto" + +#: py/objstr.c:996 +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: py/objstr.c:998 +#, c-format +msgid "unknown conversion specifier %c" +msgstr "specificatore di conversione %s sconosciuto" + +#: py/objstr.c:1029 +msgid "unmatched '{' in format" +msgstr "'{' spaiato nella stringa di formattazione" + +#: py/objstr.c:1036 +msgid "expected ':' after format specifier" +msgstr "':' atteso dopo lo specificatore di formato" + +#: py/objstr.c:1050 +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c:1055 py/objstr.c:1083 +msgid "tuple index out of range" +msgstr "indice della tupla fuori intervallo" + +#: py/objstr.c:1071 +msgid "attributes not supported yet" +msgstr "attributi non ancora supportati" + +#: py/objstr.c:1079 +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objstr.c:1171 +msgid "invalid format specifier" +msgstr "specificatore di formato non valido" + +#: py/objstr.c:1192 +msgid "sign not allowed in string format specifier" +msgstr "segno non permesso nello spcificatore di formato della stringa" + +#: py/objstr.c:1200 +msgid "sign not allowed with integer format specifier 'c'" +msgstr "segno non permesso nello spcificatore di formato 'c' della stringa" + +#: py/objstr.c:1259 +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "codice di formattaione '%c' sconosciuto per oggetto di tipo '%s'" + +#: py/objstr.c:1331 +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "codice di formattazione '%c' sconosciuto per oggetto di tipo 'float'" + +#: py/objstr.c:1343 +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: py/objstr.c:1367 +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "codice di formattazione '%c' sconosciuto per oggetto di tipo 'str'" + +#: py/objstr.c:1415 +msgid "format requires a dict" +msgstr "la formattazione richiede un dict" + +#: py/objstr.c:1424 +msgid "incomplete format key" +msgstr "" + +#: py/objstr.c:1482 +msgid "incomplete format" +msgstr "formato incompleto" + +#: py/objstr.c:1490 +msgid "not enough arguments for format string" +msgstr "argomenti non sufficienti per la stringa di formattazione" + +#: py/objstr.c:1500 +#, c-format +msgid "%%c requires int or char" +msgstr "%%c necessita di int o char" + +#: py/objstr.c:1507 +msgid "integer required" +msgstr "intero richiesto" + +#: py/objstr.c:1570 +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "carattere di formattazione '%c' (0x%x) non supportato all indice %d" + +#: py/objstr.c:1577 +msgid "not all arguments converted during string formatting" +msgstr "" +"non tutti gli argomenti sono stati convertiti durante la formatazione in " +"stringhe" + +#: py/objstr.c:2102 +msgid "can't convert to str implicitly" +msgstr "impossibile convertire a stringa implicitamente" + +#: py/objstr.c:2106 +msgid "can't convert '%q' object to %q implicitly" +msgstr "impossibile convertire l'oggetto '%q' implicitamente in %q" + +#: py/objstrunicode.c:134 +#, c-format +msgid "string indices must be integers, not %s" +msgstr "indici della stringa devono essere interi, non %s" + +#: py/objstrunicode.c:145 py/objstrunicode.c:164 +msgid "string index out of range" +msgstr "indice della stringa fuori intervallo" + +#: py/objtype.c:358 +msgid "__init__() should return None" +msgstr "__init__() deve ritornare None" + +#: py/objtype.c:360 +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() deve ritornare None, non '%s'" + +#: py/objtype.c:623 py/objtype.c:1275 py/runtime.c:1065 +msgid "unreadable attribute" +msgstr "attributo non leggibile" + +#: py/objtype.c:868 py/runtime.c:653 +msgid "object not callable" +msgstr "" + +#: py/objtype.c:870 py/runtime.c:655 +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/objtype.c:978 +msgid "type takes 1 or 3 arguments" +msgstr "tipo prende 1 o 3 argomenti" + +#: py/objtype.c:989 +msgid "cannot create instance" +msgstr "impossibile creare un istanza" + +#: py/objtype.c:991 +msgid "cannot create '%q' instances" +msgstr "creare '%q' istanze" + +#: py/objtype.c:1047 +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c:1091 py/objtype.c:1097 +msgid "type is not an acceptable base type" +msgstr "il tipo non è un tipo di base accettabile" + +#: py/objtype.c:1100 +msgid "type '%q' is not an acceptable base type" +msgstr "il tipo '%q' non è un tipo di base accettabile" + +#: py/objtype.c:1137 +msgid "multiple inheritance not supported" +msgstr "ereditarietà multipla non supportata" + +#: py/objtype.c:1164 +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c:1205 +msgid "first argument to super() must be type" +msgstr "" + +#: py/objtype.c:1370 +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" +"il secondo argomento di issubclass() deve essere una classe o una tupla di " +"classi" + +#: py/objtype.c:1384 +msgid "issubclass() arg 1 must be a class" +msgstr "il primo argomento di issubclass() deve essere una classe" + +#: py/parse.c:726 +msgid "constant must be an integer" +msgstr "la costante deve essere un intero" + +#: py/parse.c:868 +msgid "Unable to init parser" +msgstr "Inizilizzazione del parser non possibile" + +#: py/parse.c:1170 +msgid "unexpected indent" +msgstr "indentazione inaspettata" + +#: py/parse.c:1173 +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/parsenum.c:60 +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36" + +#: py/parsenum.c:151 +msgid "invalid syntax for integer" +msgstr "sintassi invalida per l'intero" + +#: py/parsenum.c:155 +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "sintassi invalida per l'intero con base %d" + +#: py/parsenum.c:339 +msgid "invalid syntax for number" +msgstr "sintassi invalida per il numero" + +#: py/parsenum.c:342 +msgid "decimal numbers not supported" +msgstr "numeri decimali non supportati" + +#: py/persistentcode.c:223 +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"File .mpy incompatibile. Aggiorna tutti i file .mpy. Vedi http://adafru.it/" +"mpy-update per più informazioni." + +#: py/persistentcode.c:326 +msgid "can only save bytecode" +msgstr "È possibile salvare solo bytecode" + +#: py/runtime.c:206 +msgid "name not defined" +msgstr "nome non definito" + +#: py/runtime.c:209 +msgid "name '%q' is not defined" +msgstr "nome '%q'non definito" + +#: py/runtime.c:304 py/runtime.c:611 +msgid "unsupported type for operator" +msgstr "tipo non supportato per l'operando" + +#: py/runtime.c:307 +msgid "unsupported type for %q: '%s'" +msgstr "tipo non supportato per %q: '%s'" + +#: py/runtime.c:614 +msgid "unsupported types for %q: '%s', '%s'" +msgstr "tipi non supportati per %q: '%s', '%s'" + +#: py/runtime.c:881 py/runtime.c:888 py/runtime.c:945 +msgid "wrong number of values to unpack" +msgstr "numero di valori da scompattare non corretto" + +#: py/runtime.c:883 py/runtime.c:947 +#, c-format +msgid "need more than %d values to unpack" +msgstr "necessari più di %d valori da scompattare" + +#: py/runtime.c:890 +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "troppi valori da scompattare (%d attesi)" + +#: py/runtime.c:984 +msgid "argument has wrong type" +msgstr "il tipo dell'argomento è errato" + +#: py/runtime.c:986 +msgid "argument should be a '%q' not a '%q'" +msgstr "l'argomento dovrebbe essere un '%q' e non un '%q'" + +#: py/runtime.c:1123 py/runtime.c:1197 +msgid "no such attribute" +msgstr "attributo inesistente" + +#: py/runtime.c:1128 +msgid "type object '%q' has no attribute '%q'" +msgstr "l'oggetto di tipo '%q' non ha l'attributo '%q'" + +#: py/runtime.c:1132 py/runtime.c:1200 +msgid "'%s' object has no attribute '%q'" +msgstr "l'oggetto '%s' non ha l'attributo '%q'" + +#: py/runtime.c:1238 +msgid "object not iterable" +msgstr "oggetto non iterabile" + +#: py/runtime.c:1241 +#, c-format +msgid "'%s' object is not iterable" +msgstr "l'oggetto '%s' non è iterabile" + +#: py/runtime.c:1260 py/runtime.c:1296 +msgid "object not an iterator" +msgstr "l'oggetto non è un iteratore" + +#: py/runtime.c:1262 py/runtime.c:1298 +#, c-format +msgid "'%s' object is not an iterator" +msgstr "l'oggetto '%s' non è un iteratore" + +#: py/runtime.c:1401 +msgid "exceptions must derive from BaseException" +msgstr "le eccezioni devono derivare da BaseException" + +#: py/runtime.c:1430 +msgid "cannot import name %q" +msgstr "impossibile imporate il nome %q" + +#: py/runtime.c:1535 +msgid "memory allocation failed, heap is locked" +msgstr "allocazione di memoria fallita, l'heap è bloccato" + +#: py/runtime.c:1539 +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "allocazione di memoria fallita, allocando %u byte" + +#: py/runtime.c:1609 +msgid "maximum recursion depth exceeded" +msgstr "profondità massima di ricorsione superata" + +#: py/sequence.c:264 +msgid "object not in sequence" +msgstr "oggetto non in sequenza" + +#: py/stream.c:96 +msgid "stream operation not supported" +msgstr "operazione di stream non supportata" + +#: py/vm.c:255 +msgid "local variable referenced before assignment" +msgstr "variabile locale richiamata prima di un assegnamento" + +#: py/vm.c:1142 +msgid "no active exception to reraise" +msgstr "nessuna eccezione attiva da rilanciare" + +#: py/vm.c:1284 +msgid "byte code not implemented" +msgstr "byte code non implementato" + +#: shared-bindings/_stage/Layer.c:71 +msgid "graphic must be 2048 bytes long" +msgstr "graphic deve essere lunga 2048 byte" + +#: shared-bindings/_stage/Layer.c:77 shared-bindings/_stage/Text.c:75 +msgid "palette must be 32 bytes long" +msgstr "la palette deve essere lunga 32 byte" + +#: shared-bindings/_stage/Layer.c:84 +msgid "map buffer too small" +msgstr "map buffer troppo piccolo" + +#: shared-bindings/_stage/Text.c:69 +msgid "font must be 2048 bytes long" +msgstr "il font deve essere lungo 2048 byte" + +#: shared-bindings/_stage/Text.c:81 +msgid "chars buffer too small" +msgstr "buffer dei caratteri troppo piccolo" + +#: shared-bindings/analogio/AnalogOut.c:118 +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut ha solo 16 bit. Il valore deve essere meno di 65536." + +#: shared-bindings/audiobusio/I2SOut.c:225 +#: shared-bindings/audioio/AudioOut.c:223 +msgid "Not playing" +msgstr "In pausa" + +#: shared-bindings/audiobusio/PDMIn.c:124 +msgid "Bit depth must be multiple of 8." +msgstr "La profondità di bit deve essere multipla di 8." + +#: shared-bindings/audiobusio/PDMIn.c:128 +msgid "Oversample must be multiple of 8." +msgstr "L'oversampling deve essere multiplo di 8." + +#: shared-bindings/audiobusio/PDMIn.c:136 +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" +"Il ritardo di avvio del microfono deve essere nell'intervallo tra 0.0 e 1.0" + +#: shared-bindings/audiobusio/PDMIn.c:193 +msgid "destination_length must be an int >= 0" +msgstr "destination_length deve essere un int >= 0" + +#: shared-bindings/audiobusio/PDMIn.c:199 +msgid "Cannot record to a file" +msgstr "Impossibile registrare in un file" + +#: shared-bindings/audiobusio/PDMIn.c:202 +msgid "Destination capacity is smaller than destination_length." +msgstr "La capacità di destinazione è più piccola di destination_length." + +#: shared-bindings/audiobusio/PDMIn.c:206 +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" +"il buffer di destinazione deve essere un array di tipo 'H' con bit_depth = 16" + +#: shared-bindings/audiobusio/PDMIn.c:208 +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"il buffer di destinazione deve essere un bytearray o un array di tipo 'B' " +"con bit_depth = 8" + +#: shared-bindings/audioio/RawSample.c:98 +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"il buffer sample_source deve essere un bytearray o un array di tipo 'h', " +"'H', 'b' o 'B'" + +#: shared-bindings/audioio/RawSample.c:104 +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-bindings/audioio/WaveFile.c:78 +#: shared-bindings/displayio/OnDiskBitmap.c:85 +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:111 shared-bindings/bitbangio/SPI.c:121 +#: shared-bindings/busio/SPI.c:133 +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c:195 shared-bindings/busio/I2C.c:210 +msgid "Buffer must be at least length 1" +msgstr "Il buffer deve essere lungo almeno 1" + +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 +msgid "Invalid polarity" +msgstr "Polarità non valida" + +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 +msgid "Invalid phase" +msgstr "Fase non valida" + +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 +msgid "Invalid number of bits" +msgstr "Numero di bit non valido" + +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 +msgid "buffer slices must be of equal length" +msgstr "slice del buffer devono essere della stessa lunghezza" + +#: shared-bindings/busio/I2C.c:120 +msgid "Function requires lock." +msgstr "" + +#: shared-bindings/busio/UART.c:102 +msgid "bits must be 7, 8 or 9" +msgstr "i bit devono essere 7, 8 o 9" + +#: shared-bindings/busio/UART.c:114 +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:211 +msgid "Invalid direction." +msgstr "Direzione non valida." + +#: shared-bindings/digitalio/DigitalInOut.c:240 +msgid "Cannot set value when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:266 +#: shared-bindings/digitalio/DigitalInOut.c:281 +msgid "Drive mode not used when direction is input." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:314 +#: shared-bindings/digitalio/DigitalInOut.c:331 +msgid "Pull not used when direction is output." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c:340 +msgid "Unsupported pull value." +msgstr "Valore di pull non supportato." + +#: shared-bindings/displayio/Bitmap.c:84 +msgid "y should be an int" +msgstr "y dovrebbe essere un int" + +#: shared-bindings/displayio/Bitmap.c:89 +msgid "row buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "buffer di riga deve essere un bytearray o un array di tipo 'b' o 'B'" + +#: shared-bindings/displayio/Bitmap.c:94 +msgid "row data must be a buffer" +msgstr "valori della riga devono essere un buffer" + +#: shared-bindings/displayio/ColorConverter.c:72 +msgid "color should be an int" +msgstr "il colore deve essere un int" + +#: shared-bindings/displayio/FourWire.c:55 +#: shared-bindings/displayio/FourWire.c:64 +msgid "displayio is a work in progress" +msgstr "" + +#: shared-bindings/displayio/Group.c:65 +msgid "Group must have size at least 1" +msgstr "Il gruppo deve avere dimensione almeno 1" + +#: shared-bindings/displayio/Palette.c:96 +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" +"buffer del colore deve essere un bytearray o un array di tipo 'b' o 'B'" + +#: shared-bindings/displayio/Palette.c:102 +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" +"il buffer del colore deve esseer di 3 byte (RGB) o 4 byte (RGB + pad byte)" + +#: shared-bindings/displayio/Palette.c:106 +msgid "color must be between 0x000000 and 0xffffff" +msgstr "il colore deve essere compreso tra 0x000000 e 0xffffff" + +#: shared-bindings/displayio/Palette.c:110 +msgid "color buffer must be a buffer or int" +msgstr "il buffer del colore deve essere un buffer o un int" + +#: shared-bindings/displayio/Palette.c:123 +#: shared-bindings/displayio/Palette.c:137 +msgid "palette_index should be an int" +msgstr "palette_index deve essere un int" + +#: shared-bindings/displayio/Sprite.c:48 +msgid "position must be 2-tuple" +msgstr "position deve essere una 2-tuple" + +#: shared-bindings/displayio/Sprite.c:97 +msgid "unsupported bitmap type" +msgstr "tipo di bitmap non supportato" + +#: shared-bindings/displayio/Sprite.c:162 +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader deve essere displayio.Palette o displayio.ColorConverter" + +#: shared-bindings/gamepad/GamePad.c:100 +msgid "too many arguments" +msgstr "troppi argomenti" + +#: shared-bindings/gamepad/GamePad.c:104 +msgid "expected a DigitalInOut" +msgstr "DigitalInOut atteso" + +#: shared-bindings/i2cslave/I2CSlave.c:98 +msgid "can't convert address to int" +msgstr "impossible convertire indirizzo in int" + +#: shared-bindings/i2cslave/I2CSlave.c:101 +msgid "address out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/i2cslave/I2CSlave.c:107 +msgid "addresses is empty" +msgstr "gli indirizzi sono vuoti" + +#: shared-bindings/microcontroller/Pin.c:89 +#: shared-bindings/neopixel_write/__init__.c:67 +#: shared-bindings/pulseio/PulseOut.c:75 +msgid "Expected a %q" +msgstr "Atteso un %q" + +#: shared-bindings/microcontroller/Pin.c:100 +msgid "%q in use" +msgstr "%q in uso" + +#: shared-bindings/microcontroller/__init__.c:126 +msgid "Invalid run mode." +msgstr "Modalità di esecuzione non valida." + +#: shared-bindings/multiterminal/__init__.c:68 +msgid "Stream missing readinto() or write() method." +msgstr "Metodi mancanti readinto() o write() allo stream." + +#: shared-bindings/nvm/ByteArray.c:99 +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:104 +msgid "Array values should be single bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c:111 shared-bindings/nvm/ByteArray.c:141 +msgid "Unable to write to nvm." +msgstr "Imposibile scrivere su nvm." + +#: shared-bindings/nvm/ByteArray.c:137 +msgid "Bytes must be between 0 and 255." +msgstr "I byte devono essere compresi tra 0 e 255" + +#: shared-bindings/os/__init__.c:200 +msgid "No hardware random available" +msgstr "Nessun generatore hardware di numeri casuali disponibile" + +#: shared-bindings/pulseio/PWMOut.c:164 +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" +"duty_cycle del PWM deve essere compresa tra 0 e 65535 inclusiva (risoluzione " +"a 16 bit)" + +#: shared-bindings/pulseio/PWMOut.c:195 +msgid "" +"PWM frequency not writeable when variable_frequency is False on construction." +msgstr "" +"frequenza PWM frequency non è scrivibile quando variable_frequency è " +"impostato nel costruttore a False." + +#: shared-bindings/pulseio/PulseIn.c:275 +msgid "Cannot delete values" +msgstr "Impossibile cancellare valori" + +#: shared-bindings/pulseio/PulseIn.c:281 +msgid "Slices not supported" +msgstr "Slice non supportate" + +#: shared-bindings/pulseio/PulseIn.c:287 +msgid "index must be int" +msgstr "l'indice deve essere int" + +#: shared-bindings/pulseio/PulseIn.c:293 +msgid "Read-only" +msgstr "Sola lettura" + +#: shared-bindings/pulseio/PulseOut.c:134 +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/random/__init__.c:92 shared-bindings/random/__init__.c:100 +msgid "stop not reachable from start" +msgstr "stop non raggiungibile dall'inizio" + +#: shared-bindings/random/__init__.c:111 +msgid "step must be non-zero" +msgstr "step deve essere non zero" + +#: shared-bindings/random/__init__.c:114 +msgid "invalid step" +msgstr "step non valida" + +#: shared-bindings/random/__init__.c:146 +msgid "empty sequence" +msgstr "sequenza vuota" + +#: shared-bindings/rtc/RTC.c:40 shared-bindings/rtc/RTC.c:44 +#: shared-bindings/time/__init__.c:190 +msgid "RTC is not supported on this board" +msgstr "RTC non supportato su questa scheda" + +#: shared-bindings/rtc/RTC.c:52 +msgid "RTC calibration is not supported on this board" +msgstr "calibrazione RTC non supportata su questa scheda" + +#: shared-bindings/storage/__init__.c:77 +msgid "filesystem must provide mount method" +msgstr "il filesystem deve fornire un metodo di mount" + +#: shared-bindings/supervisor/__init__.c:93 +msgid "Brightness must be between 0 and 255" +msgstr "La luminosità deve essere compreso tra 0 e 255" + +#: shared-bindings/supervisor/__init__.c:119 +msgid "Stack size must be at least 256" +msgstr "La dimensione dello stack deve essere almeno 256" + +#: shared-bindings/time/__init__.c:78 +msgid "sleep length must be non-negative" +msgstr "la lunghezza di sleed deve essere non negativa" + +#: shared-bindings/time/__init__.c:88 +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() prende esattamente un argomento" + +#: shared-bindings/time/__init__.c:91 +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c:169 shared-bindings/time/__init__.c:250 +msgid "Tuple or struct_time argument required" +msgstr "Tupla o struct_time richiesto come argomento" + +#: shared-bindings/time/__init__.c:174 shared-bindings/time/__init__.c:255 +msgid "function takes exactly 9 arguments" +msgstr "la funzione prende esattamente 9 argomenti" + +#: shared-bindings/time/__init__.c:226 shared-bindings/time/__init__.c:259 +msgid "timestamp out of range for platform time_t" +msgstr "timestamp è fuori intervallo per il time_t della piattaforma" + +#: shared-bindings/touchio/TouchIn.c:173 +msgid "threshold must be in the range 0-65536" +msgstr "la soglia deve essere nell'intervallo 0-65536" + +#: shared-bindings/util.c:38 +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"L'oggetto è stato deinizializzato e non può essere più usato. Crea un nuovo " +"oggetto." + +#: shared-module/audioio/WaveFile.c:61 +msgid "Invalid wave file" +msgstr "File wave non valido" + +#: shared-module/audioio/WaveFile.c:69 +msgid "Invalid format chunk size" +msgstr "" + +#: shared-module/audioio/WaveFile.c:83 +msgid "Unsupported format" +msgstr "Formato non supportato" + +#: shared-module/audioio/WaveFile.c:99 +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: shared-module/audioio/WaveFile.c:107 +msgid "Invalid file" +msgstr "File non valido" + +#: shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "Impossibile allocare il primo buffer" + +#: shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "Impossibile allocare il secondo buffer" + +#: shared-module/bitbangio/I2C.c:58 +msgid "Clock stretch too long" +msgstr "" + +#: shared-module/bitbangio/SPI.c:45 +msgid "Clock pin init failed." +msgstr "Inizializzazione del pin di clock fallita." + +#: shared-module/bitbangio/SPI.c:51 +msgid "MOSI pin init failed." +msgstr "inizializzazione del pin MOSI fallita." + +#: shared-module/bitbangio/SPI.c:62 +msgid "MISO pin init failed." +msgstr "inizializzazione del pin MISO fallita." + +#: shared-module/bitbangio/SPI.c:122 +msgid "Cannot write without MOSI pin." +msgstr "Impossibile scrivere senza pin MOSI." + +#: shared-module/bitbangio/SPI.c:177 +msgid "Cannot read without MISO pin." +msgstr "Impossibile leggere senza pin MISO." + +#: shared-module/bitbangio/SPI.c:241 +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Impossibile trasferire senza i pin MOSI e MISO." + +#: shared-module/displayio/Bitmap.c:49 +msgid "Only bit maps of 8 bit color or less are supported" +msgstr "Sono supportate solo bitmap con colori a 8 bit o meno" + +#: shared-module/displayio/Bitmap.c:69 +msgid "row must be packed and word aligned" +msgstr "la riga deve essere compattata e allineata alla parola" + +#: shared-module/displayio/Group.c:39 +msgid "Group full" +msgstr "Gruppo pieno" + +#: shared-module/displayio/Group.c:48 +msgid "Group empty" +msgstr "Gruppo vuoto" + +#: shared-module/displayio/OnDiskBitmap.c:49 +msgid "Invalid BMP file" +msgstr "File BMP non valido" + +#: shared-module/displayio/OnDiskBitmap.c:59 +#, c-format +msgid "Only Windows format, uncompressed BMP supported %d" +msgstr "Formato solo di Windows, BMP non compresso supportato %d" + +#: shared-module/displayio/OnDiskBitmap.c:64 +#, c-format +msgid "Only true color (24 bpp or higher) BMP supported %x" +msgstr "Solo BMP true color (24 bpp o superiore) sono supportati %x" + +#: shared-module/struct/__init__.c:39 +msgid "'S' and 'O' are not supported format types" +msgstr "'S' e 'O' non sono formati supportati" + +#: shared-module/struct/__init__.c:83 +msgid "too many arguments provided with the given format" +msgstr "troppi argomenti forniti con il formato specificato" -- cgit v1.2.3 From 6d9c2c52540fd59f8d1addbd5088757844f3d01c Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 22:37:49 +1100 Subject: Documentation builds (though has no real content yet) --- shared-bindings/network/__init__.c | 7 +++++++ shared-bindings/wiznet/__init__.c | 17 +++++++++++++++++ shared-bindings/wiznet/wiznet5k.c | 10 +++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index ad42fea5f..f28d5265c 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -36,6 +36,13 @@ #include "shared-bindings/network/__init__.h" +//| :mod:`network` --- Network Interface Management +//| =============================================== +//| +//| .. module:: network +//| :synopsis: Network Interface Management +//| :platform: SAMD + #if MICROPY_PY_NETWORK /// \module network - network configuration diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index e448d2ef1..fbdac3885 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -35,6 +35,23 @@ #include "shared-bindings/network/__init__.h" +//| :mod:`wiznet` --- Support for WizNet hardware +//| ============================================= +//| +//| .. module:: wiznet +//| :synopsis: Support for WizNet hardware +//| :platform: SAMD +//| +//| Doc content goes here +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| wiznet5k +//| + extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; STATIC const mp_rom_map_elem_t mp_module_wiznet_globals_table[] = { diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index b561806ae..ccbd2b115 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -50,7 +50,15 @@ #include "internet/dns/dns.h" #include "internet/dhcp/dhcp.h" -/// \moduleref network +//| .. currentmodule:: wiznet +//| +//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface +//| =============================================================== +//| +//| .. class:: WIZNET5K(spi, cs, rst) +//| +//| Create a new WIZNET5500 interface using the specified pins +//| typedef struct _wiznet5k_obj_t { mp_obj_base_t base; -- cgit v1.2.3 From 38798446b52fb587b52763117a72969761c9a18c Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 9 Oct 2018 22:57:42 +1100 Subject: Exclude .direnv from sphinx-build --- conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conf.py b/conf.py index 0f363923f..43709b503 100644 --- a/conf.py +++ b/conf.py @@ -84,6 +84,7 @@ version = release = '0.0.0' # directories to ignore when looking for source files. exclude_patterns = ["**/build*", ".venv", + ".direnv", "docs/README.md", "drivers", "examples", -- cgit v1.2.3 From 6da25c8893afedfc195327f597fd3b0b45fc65d8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Oct 2018 13:28:00 -0700 Subject: Rename stop to stop_voice in case we want stop to stop everything later. --- shared-bindings/audioio/Mixer.c | 16 ++++++++-------- shared-bindings/audioio/Mixer.h | 2 +- shared-module/audioio/Mixer.c | 5 +---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audioio/Mixer.c index d353daa78..dc7a12ebc 100644 --- a/shared-bindings/audioio/Mixer.c +++ b/shared-bindings/audioio/Mixer.c @@ -150,7 +150,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, aud //| //| Sample must be an `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`. //| -//| If other samples are already playing, the encodings must match. +//| The sample must match the Mixer's encoding settings given in the constructor. //| STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_voice, ARG_loop }; @@ -171,24 +171,24 @@ STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, } MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_play_obj, 1, audioio_mixer_obj_play); -//| .. method:: stop(voice=0) +//| .. method:: stop_voice(voice=0) //| -//| Stops playback and resets to the start of the sample on the given channel. +//| Stops playback of the sample on the given voice. //| -STATIC mp_obj_t audioio_mixer_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, }; audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - common_hal_audioio_mixer_stop(self, args[ARG_voice].u_int); + common_hal_audioio_mixer_stop_voice(self, args[ARG_voice].u_int); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_obj, 1, audioio_mixer_obj_stop); +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_stop_voice); //| .. attribute:: playing //| @@ -233,7 +233,7 @@ STATIC const mp_rom_map_elem_t audioio_mixer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_mixer___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_mixer_play_obj) }, - { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audioio_mixer_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audioio_mixer_stop_voice_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audioio_mixer_playing_obj) }, diff --git a/shared-bindings/audioio/Mixer.h b/shared-bindings/audioio/Mixer.h index ad1a9fe05..832072b8f 100644 --- a/shared-bindings/audioio/Mixer.h +++ b/shared-bindings/audioio/Mixer.h @@ -44,7 +44,7 @@ void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self); bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self); void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t voice, bool loop); -void common_hal_audioio_mixer_stop(audioio_mixer_obj_t* self, uint8_t voice); +void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice); bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self); uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self); diff --git a/shared-module/audioio/Mixer.c b/shared-module/audioio/Mixer.c index 0709e2e42..8020a621e 100644 --- a/shared-module/audioio/Mixer.c +++ b/shared-module/audioio/Mixer.c @@ -110,7 +110,7 @@ void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, u voice->more_data = result == GET_BUFFER_MORE_DATA; } -void common_hal_audioio_mixer_stop(audioio_mixer_obj_t* self, uint8_t voice) { +void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice) { self->voice[voice].sample = NULL; } @@ -131,8 +131,6 @@ void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, } } - #pragma GCC push_options - #pragma GCC optimize ("O0") uint32_t add8signed(uint32_t a, uint32_t b) { #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) return __QADD8(a, b); @@ -152,7 +150,6 @@ uint32_t add8signed(uint32_t a, uint32_t b) { return result; #endif } - #pragma GCC pop_options uint32_t add8unsigned(uint32_t a, uint32_t b) { #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) -- cgit v1.2.3 From 570ac05145cecc2e1c61cc0ba710e6db9b2af5d2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Oct 2018 13:57:45 -0700 Subject: Add Mixer strings to Italian translation --- locale/circuitpython.pot | 2 +- locale/fr.po | 10 ++++---- locale/it_IT.po | 60 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index d50e117e1..04f16be3b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 13:56-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr.po b/locale/fr.po index 0216d35f9..1a5af3fef 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 13:56-0700\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2510,10 +2510,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" - #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" diff --git a/locale/it_IT.po b/locale/it_IT.po index dd8b41f76..9318952c2 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 10:54+0200\n" +"POT-Creation-Date: 2018-10-09 13:56-0700\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -231,7 +231,7 @@ msgstr "" msgid "soft reboot\n" msgstr "soft reboot\n" -#: ports/atmel-samd/audio_dma.c:285 +#: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 msgid "All sync event channels in use" msgstr "Tutti i canali di eventi sincronizzati in uso" @@ -2064,6 +2064,26 @@ msgstr "" "il buffer di destinazione deve essere un bytearray o un array di tipo 'B' " "con bit_depth = 8" +#: shared-bindings/audioio/Mixer.c:94 +#, fuzzy +msgid "Invalid voice count" +msgstr "Tipo di servizio non valido" + +#: shared-bindings/audioio/Mixer.c:99 +#, fuzzy +msgid "Invalid channel count" +msgstr "Argomento non valido" + +#: shared-bindings/audioio/Mixer.c:103 +#, fuzzy +msgid "Sample rate must be positive" +msgstr "STA deve essere attiva" + +#: shared-bindings/audioio/Mixer.c:107 +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "i bit devono essere 7, 8 o 9" + #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " @@ -2364,6 +2384,34 @@ msgstr "" "L'oggetto è stato deinizializzato e non può essere più usato. Crea un nuovo " "oggetto." +#: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 +msgid "Couldn't allocate first buffer" +msgstr "Impossibile allocare il primo buffer" + +#: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 +msgid "Couldn't allocate second buffer" +msgstr "Impossibile allocare il secondo buffer" + +#: shared-module/audioio/Mixer.c:82 +msgid "Voice index too high" +msgstr "" + +#: shared-module/audioio/Mixer.c:85 +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:88 +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:91 +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audioio/Mixer.c:100 +msgid "The sample's signedness does not match the mixer's" +msgstr "" + #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" msgstr "File wave non valido" @@ -2384,14 +2432,6 @@ msgstr "" msgid "Invalid file" msgstr "File non valido" -#: shared-module/audioio/WaveFile.c:117 -msgid "Couldn't allocate first buffer" -msgstr "Impossibile allocare il primo buffer" - -#: shared-module/audioio/WaveFile.c:123 -msgid "Couldn't allocate second buffer" -msgstr "Impossibile allocare il secondo buffer" - #: shared-module/bitbangio/I2C.c:58 msgid "Clock stretch too long" msgstr "" -- cgit v1.2.3 From bc0a13552478036b75e351c21b84ae3fa3f45d30 Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Tue, 9 Oct 2018 18:25:51 -0400 Subject: replacing change to input() with separate method to check for USB Serial input --- py/modbuiltins.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 8dbcec7e3..fc7ec24c7 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -34,7 +34,6 @@ #include "py/runtime.h" #include "py/builtin.h" #include "py/stream.h" -#include "py/obj.h" /* For get_int */ #include "supervisor/shared/translate.h" @@ -234,41 +233,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hex_obj, mp_builtin_hex); #define mp_hal_readline readline #endif -#include "usb.h" - STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) { - if (n_args >= 1) { + if (n_args == 1) { mp_obj_print(args[0], PRINT_STR); } - if (n_args == 2) - { - if (!mp_obj_is_true(args[1])) - { /* If they pass 0 or False, return immediately if there's no text available */ - if (!usb_bytes_available()) - { - return mp_const_none; - } - } - else if (MP_OBJ_IS_INT(args[1])) - { - /* Timeout has been sent... check for USB input for that # of millis */ - mp_uint_t target = mp_hal_ticks_ms() + mp_obj_get_int(args[1]); - bool bytesAvaliable = false; - - while (mp_hal_ticks_ms() < target) - { - if (usb_bytes_available()) - { - bytesAvaliable = true; - break; - } - } - if (!bytesAvaliable) - return mp_const_none; - } - } - - vstr_t line; vstr_init(&line, 16); int ret = mp_hal_readline(&line, ""); @@ -280,7 +248,7 @@ STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) { } return mp_obj_new_str_from_vstr(&mp_type_str, &line); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 2, mp_builtin_input); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input); #endif -- cgit v1.2.3 From 9f94712ad10193c4fc6d888ef3ebc611bc0e011c Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Tue, 9 Oct 2018 18:37:52 -0400 Subject: replacing change to input() with separate method to check for USB Serial input --- ports/atmel-samd/common-hal/supervisor/Runtime.c | 4 ++++ ports/nrf/common-hal/supervisor/Runtime.c | 4 ++++ shared-bindings/supervisor/Runtime.c | 20 ++++++++++++++++++++ shared-bindings/supervisor/Runtime.h | 2 ++ 4 files changed, 30 insertions(+) diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c index 8efe7cb78..2636fe646 100755 --- a/ports/atmel-samd/common-hal/supervisor/Runtime.c +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -32,3 +32,7 @@ bool common_hal_get_serial_connected(void) { return (bool) usb_connected(); } +bool common_hal_get_serial_bytes_available(void) { + return (bool) usb_bytes_available(); +} + diff --git a/ports/nrf/common-hal/supervisor/Runtime.c b/ports/nrf/common-hal/supervisor/Runtime.c index b73a94a1b..feab6987d 100755 --- a/ports/nrf/common-hal/supervisor/Runtime.c +++ b/ports/nrf/common-hal/supervisor/Runtime.c @@ -32,3 +32,7 @@ bool common_hal_get_serial_connected(void) { return (bool) serial_connected(); } +bool common_hal_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); +} + diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index b061595cf..1cf2a3548 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -80,8 +80,28 @@ const mp_obj_property_t supervisor_serial_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; +/*Added to allow for polling of USB Console*/ +STATIC mp_obj_t supervisor_get_serial_bytes_available(mp_obj_t self){ + if (!common_hal_get_serial_bytes_available()) { + return mp_const_false; + } + else { + return mp_const_true; + } +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_bytes_available_obj, supervisor_get_serial_bytes_available); + +const mp_obj_property_t supervisor_serial_bytes_available_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&supervisor_get_serial_bytes_available_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_serial_bytes_available_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index 4a67925ec..864b070cd 100755 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -35,6 +35,8 @@ const mp_obj_type_t supervisor_runtime_type; bool common_hal_get_serial_connected(void); +bool common_hal_get_serial_bytes_available(void); + //TODO: placeholders for future functions //bool common_hal_get_repl_active(void); //bool common_hal_get_usb_enumerated(void); -- cgit v1.2.3 From 91a88cf5685b88708cae501f4f7dbf0e8a4e6e17 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 9 Oct 2018 20:52:55 -0400 Subject: Allow variable freq PWMOut; use multiple channels if same freq --- locale/circuitpython.pot | 11 +- locale/de_DE.po | 12 +- locale/en_US.po | 11 +- locale/es.po | 12 +- locale/fil.po | 13 +- locale/fr.po | 13 +- locale/it_IT.po | 13 +- locale/pt_BR.po | 12 +- ports/nrf/common-hal/busio/SPI.c | 2 +- ports/nrf/common-hal/pulseio/PWMOut.c | 311 +++++++++++++++++----------------- ports/nrf/common-hal/pulseio/PWMOut.h | 14 +- shared-bindings/pulseio/PWMOut.c | 2 +- 12 files changed, 240 insertions(+), 186 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 04f16be3b..83662734a 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 13:56-0700\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -413,7 +413,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "" @@ -728,6 +729,10 @@ msgstr "" msgid "Can not get temperature. status: 0x%02x" msgstr "" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +msgid "All PWM peripherals are in use" +msgstr "" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "" @@ -2239,7 +2244,7 @@ msgstr "" #: shared-bindings/pulseio/PWMOut.c:195 msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 diff --git a/locale/de_DE.po b/locale/de_DE.po index 51c3c4504..de9a21e96 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -422,7 +422,8 @@ msgstr "Reset zum bootloader nicht möglich da bootloader nicht vorhanden" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Ungültige PWM Frequenz" @@ -741,6 +742,11 @@ msgstr "" msgid "Can not get temperature. status: 0x%02x" msgstr "" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Alle timer werden benutzt" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "" @@ -2257,7 +2263,7 @@ msgstr "" #: shared-bindings/pulseio/PWMOut.c:195 msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 diff --git a/locale/en_US.po b/locale/en_US.po index 4b4ee2415..15c97e329 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -413,7 +413,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "" @@ -728,6 +729,10 @@ msgstr "" msgid "Can not get temperature. status: 0x%02x" msgstr "" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +msgid "All PWM peripherals are in use" +msgstr "" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "" @@ -2239,7 +2244,7 @@ msgstr "" #: shared-bindings/pulseio/PWMOut.c:195 msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 diff --git a/locale/es.po b/locale/es.po index bc70f1d81..324fe0720 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -428,7 +428,8 @@ msgstr "No se puede reiniciar en bootloader porque no hay bootloader presente." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Frecuencia PWM inválida" @@ -745,6 +746,11 @@ msgstr "busio.UART no disponible" msgid "Can not get temperature. status: 0x%02x" msgstr "No se puede obtener la temperatura. status: 0x%02x" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Todos los timers están siendo utilizados" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "No se pueden aplicar los parámetros GAP." @@ -2285,7 +2291,7 @@ msgstr "" #: shared-bindings/pulseio/PWMOut.c:195 msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 diff --git a/locale/fil.po b/locale/fil.po index 192ec58a5..e4f3105c9 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -425,7 +425,8 @@ msgstr "Hindi ma-reset sa bootloader dahil walang bootloader." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Mali ang PWM frequency" @@ -747,6 +748,11 @@ msgstr "" msgid "Can not get temperature. status: 0x%02x" msgstr "Hindi makuha ang temperatura. status 0x%02x" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Lahat ng timer ginagamit" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "Hindi ma-apply ang GAP parameters." @@ -2301,8 +2307,9 @@ msgid "" msgstr "PWM duty_cycle ay dapat sa loob ng 0 at 65535 (16 bit resolution)" #: shared-bindings/pulseio/PWMOut.c:195 +#, fuzzy msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" "PWM frequency hindi maisulat kapag variable_frequency ay False sa pag buo." diff --git a/locale/fr.po b/locale/fr.po index 1a5af3fef..02beae6d0 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 13:56-0700\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -421,7 +421,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Fréquence de PWM invalide" @@ -744,6 +745,11 @@ msgstr "busio.UART n'est pas disponible" msgid "Can not get temperature. status: 0x%02x" msgstr "Impossible de lire la température. status: 0x%02x" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Tous les timers sont utilisés" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "Impossible d'appliquer les paramètres GAP" @@ -2296,8 +2302,9 @@ msgstr "" "bits)" #: shared-bindings/pulseio/PWMOut.c:195 +#, fuzzy msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" "La fréquence de PWM n'est pas modifiable quand variable_frequency est False " "à laconstruction." diff --git a/locale/it_IT.po b/locale/it_IT.po index 9318952c2..5490c699c 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 13:56-0700\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -429,7 +429,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Frequenza PWM non valida" @@ -748,6 +749,11 @@ msgstr "busio.UART non ancora implementato" msgid "Can not get temperature. status: 0x%02x" msgstr "Impossibile leggere la temperatura. status: 0x%02x" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Tutte le periferiche SPI sono in uso" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "Impossibile applicare i parametri GAP." @@ -2286,8 +2292,9 @@ msgstr "" "a 16 bit)" #: shared-bindings/pulseio/PWMOut.c:195 +#, fuzzy msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" "frequenza PWM frequency non è scrivibile quando variable_frequency è " "impostato nel costruttore a False." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 9b92333fc..f3d055c08 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-07 02:07+0300\n" +"POT-Creation-Date: 2018-10-09 20:51-0400\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -413,7 +413,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:227 +#: ports/nrf/common-hal/pulseio/PWMOut.c:120 +#: ports/nrf/common-hal/pulseio/PWMOut.c:232 msgid "Invalid PWM frequency" msgstr "Frequência PWM inválida" @@ -730,6 +731,11 @@ msgstr "busio.UART não disponível" msgid "Can not get temperature. status: 0x%02x" msgstr "Não pode obter a temperatura. status: 0x%02x" +#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Todos os temporizadores em uso" + #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." msgstr "Não é possível aplicar parâmetros GAP." @@ -2245,7 +2251,7 @@ msgstr "" #: shared-bindings/pulseio/PWMOut.c:195 msgid "" -"PWM frequency not writeable when variable_frequency is False on construction." +"PWM frequency not writable when variable_frequency is False on construction." msgstr "" #: shared-bindings/pulseio/PulseIn.c:275 diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 405d19c23..f094b7f24 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -61,7 +61,7 @@ STATIC spim_peripheral_t spim_peripherals[] = { void spi_reset(void) { for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { - nrfx_spim_uninit(&spim_peripherals[i].spim); + nrf_spim_disable(spim_peripherals[i].spim.p_reg); } } diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c index c3c51d566..7b5741e35 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.c +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -30,154 +30,159 @@ #include "py/runtime.h" #include "common-hal/pulseio/PWMOut.h" -#include "nrf_gpio.h" #include "shared-bindings/pulseio/PWMOut.h" #include "supervisor/shared/translate.h" -#define PWM_MAX_MODULE 3 -#define PWM_MAX_CHANNEL 4 +#include "nrf_gpio.h" #define PWM_MAX_FREQ (16000000) -NRF_PWM_Type* const pwm_arr[PWM_MAX_MODULE] = { NRF_PWM0, NRF_PWM1, NRF_PWM2 }; - -uint16_t _seq0[PWM_MAX_MODULE][PWM_MAX_CHANNEL]; - - -static int pin2channel(NRF_PWM_Type* pwm, uint8_t pin) -{ - for(int i=0; i < PWM_MAX_CHANNEL; i++) - { - if ( pwm->PSEL.OUT[i] == ((uint32_t)pin) ) return i; - } - - return -1; -} - -static int find_free_channel(NRF_PWM_Type* pwm) -{ - for(int i=0; i < PWM_MAX_CHANNEL; i++) - { - if (pwm->PSEL.OUT[i] == 0xFFFFFFFFUL) - { - return i; +STATIC NRF_PWM_Type* pwms[] = { +#if NRFX_CHECK(NRFX_PWM0_ENABLED) + NRF_PWM0, +#endif +#if NRFX_CHECK(NRFX_PWM1_ENABLED) + NRF_PWM1, +#endif +#if NRFX_CHECK(NRFX_PWM2_ENABLED) + NRF_PWM2, +#endif +#if NRFX_CHECK(NRFX_PWM3_ENABLED) + NRF_PWM3, +#endif +}; + +#define CHANNELS_PER_PWM 4 + +STATIC uint16_t pwm_seq[MP_ARRAY_SIZE(pwms)][CHANNELS_PER_PWM]; + +void pwmout_reset(void) { + for(int i=0; i < MP_ARRAY_SIZE(pwms); i++) { + NRF_PWM_Type* pwm = pwms[i]; + + pwm->ENABLE = 0; + pwm->MODE = PWM_MODE_UPDOWN_Up; + pwm->DECODER = PWM_DECODER_LOAD_Individual; + pwm->LOOP = 0; + pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz + pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz + + pwm->SEQ[0].PTR = (uint32_t) pwm_seq[i]; + pwm->SEQ[0].CNT = CHANNELS_PER_PWM; // default mode is Individual --> count must be 4 + pwm->SEQ[0].REFRESH = 0; + pwm->SEQ[0].ENDDELAY = 0; + + pwm->SEQ[1].PTR = 0; + pwm->SEQ[1].CNT = 0; + pwm->SEQ[1].REFRESH = 0; + pwm->SEQ[1].ENDDELAY = 0; + + for(int ch =0; ch < CHANNELS_PER_PWM; ch++) { + pwm_seq[i][ch] = (1 << 15); // polarity = 0 + } } - } - - return -1; } -static bool pwm_is_unused(NRF_PWM_Type* pwm) -{ - for(int i=0; i < PWM_MAX_CHANNEL; i++) - { - if (pwm->PSEL.OUT[i] != 0xFFFFFFFFUL) - { - return false; +// Find the smallest prescaler value that will allow the divisor to be in range. +// This allows the most accuracy. +bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t *base_clock) { + uint32_t divisor = 1; + // Use a 32-bit number so we don't overflow the uint16_t; + uint32_t tentative_countertop; + for (*base_clock = PWM_PRESCALER_PRESCALER_DIV_1; + *base_clock <= PWM_PRESCALER_PRESCALER_DIV_128; + (*base_clock)++) { + tentative_countertop = PWM_MAX_FREQ / divisor / frequency; + // COUNTERTOP must be 3..32767, according to datasheet, but 3 doesn't work. 4 does. + if (tentative_countertop <= 32767 && tentative_countertop >= 4) { + // In range, OK to return. + *countertop = tentative_countertop; + return true; + } + divisor *= 2; } - } - return true; + return false; } -static void find_new_pwm(pulseio_pwmout_obj_t* self) -{ - // First find unused PWM module - for(int i=0; ipwm = pwm_arr[i]; - self->channel = 0; - return; - } - } - - // Find available channel in a using PWM - for(int i=0; i= 0 ) - { - self->pwm = pwm_arr[i]; - self->channel = (uint8_t) ch; - return; +void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { + + // We don't use the nrfx driver here because we want to dynamically allocate channels + // as needed in an already-enabled PWM. + + uint16_t countertop; + nrf_pwm_clk_t base_clock; + if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) { + mp_raise_ValueError(translate("Invalid PWM frequency")); } - } -} -void pwmout_reset(void) -{ - for(int i=0; iMODE = PWM_MODE_UPDOWN_Up; - pwm->DECODER = PWM_DECODER_LOAD_Individual; - pwm->LOOP = 0; - pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz - pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz - - pwm->SEQ[0].PTR = (uint32_t) _seq0[i]; - pwm->SEQ[0].CNT = PWM_MAX_CHANNEL; // default mode is Individual --> count must be 4 - pwm->SEQ[0].REFRESH = 0; - pwm->SEQ[0].ENDDELAY = 0; - - pwm->SEQ[1].PTR = 0; - pwm->SEQ[1].CNT = 0; - pwm->SEQ[1].REFRESH = 0; - pwm->SEQ[1].ENDDELAY = 0; - - for(int ch =0; ch < PWM_MAX_CHANNEL; ch++) - { - _seq0[i][ch] = (1UL << 15); // polarity = 0 + self->pwm = NULL; + self->channel = CHANNELS_PER_PWM; // out-of-range value. + bool pwm_already_in_use; + NRF_PWM_Type* pwm; + + for (size_t i = 0 ; i < MP_ARRAY_SIZE(pwms); i++) { + pwm = pwms[i]; + pwm_already_in_use = pwm->ENABLE & SPIM_ENABLE_ENABLE_Msk; + if (pwm_already_in_use) { + if (variable_frequency) { + // Variable frequency requires exclusive use of a PWM, so try the next one. + continue; + } + + // PWM is in use, but see if it's set to the same frequency we need. If so, + // look for a free channel. + if (pwm->COUNTERTOP == countertop && pwm->PRESCALER == base_clock) { + for (size_t chan = 0; chan < CHANNELS_PER_PWM; chan++) { + if (pwm->PSEL.OUT[chan] == 0xFFFFFFFF) { + // Channel is free. + self->pwm = pwm; + self->channel = chan; + break; + } + } + // Did we find a channel? If not, loop and check the next pwm. + if (self->pwm != NULL) { + break; + } + } + } else { + // PWM not yet in use, so we can start to use it. Use channel 0. + self->pwm = pwm; + self->channel = 0; + break; + } } - } -} -void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, - uint16_t duty, - uint32_t frequency, - bool variable_frequency) { - self->pwm = NULL; - self->pin = pin; - - // check if mapped to PWM channel already - for(int i=0; inumber); - if ( ch >= 0 ) - { - self->pwm = pwm_arr[i]; - self->channel = (uint8_t) ch; - break; + if (self->pwm == NULL) { + mp_raise_ValueError(translate("All PWM peripherals are in use")); } - } - // Haven't mapped before - if ( !self->pwm ) - { - find_new_pwm(self); - } + self->pin_number = pin->number; + claim_pin(pin); + + self->frequency = frequency; + self->variable_frequency = variable_frequency; - if (self->pwm) - { - nrf_gpio_cfg_output(pin->number); + nrf_gpio_cfg_output(self->pin_number); // disable before mapping pin channel - self->pwm->ENABLE = 0; + nrf_pwm_disable(pwm); - self->pwm->PSEL.OUT[self->channel] = pin->number; + if (!pwm_already_in_use) { + nrf_pwm_configure(pwm, base_clock, NRF_PWM_MODE_UP, countertop); + } - self->pwm->COUNTERTOP = (PWM_MAX_FREQ/frequency); - self->freq = frequency; - self->variable_freq = variable_frequency; + // Connect channel to pin, without disturbing other channels. + pwm->PSEL.OUT[self->channel] = pin->number; - self->pwm->ENABLE = 1; + nrf_pwm_enable(pwm); common_hal_pulseio_pwmout_set_duty_cycle(self, duty); - } } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { @@ -185,57 +190,59 @@ bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { } void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { - if (common_hal_pulseio_pwmout_deinited(self)) { - return; - } + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } - self->pwm->ENABLE = 0; + nrf_gpio_cfg_default(self->pin_number); - self->pwm->PSEL.OUT[self->channel] = 0xFFFFFFFFUL; + nrf_pwm_disable(self->pwm); - // re-enable PWM module if there is other active channel - for(int i=0; i < PWM_MAX_CHANNEL; i++) - { - if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFFUL) - { - self->pwm->ENABLE = 1; - break; - } - } + self->pwm->PSEL.OUT[self->channel] = 0xFFFFFFFF; - nrf_gpio_cfg_default(self->pin->number); + // Re-enable PWM module if there is another active channel. + for(int i=0; i < CHANNELS_PER_PWM; i++) { + if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFF) { + nrf_pwm_enable(self->pwm); + break; + } + } - self->pwm = NULL; - self->pin = mp_const_none; + self->pwm = NULL; } -void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { - self->duty = duty; +void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty_cycle) { + self->duty_cycle = duty_cycle; - uint16_t* p_value = ((uint16_t*)self->pwm->SEQ[0].PTR) + self->channel; - *p_value = ((duty * self->pwm->COUNTERTOP) / 0xFFFF) | (1 << 15); + uint16_t* p_value = ((uint16_t*)self->pwm->SEQ[0].PTR) + self->channel; + *p_value = ((duty_cycle * self->pwm->COUNTERTOP) / 0xFFFF) | (1 << 15); - self->pwm->TASKS_SEQSTART[0] = 1; + self->pwm->TASKS_SEQSTART[0] = 1; } uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { - return self->duty; + return self->duty_cycle; } void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) { - if (frequency == 0 || frequency > 16000000) { - mp_raise_ValueError(translate("Invalid PWM frequency")); - } + // COUNTERTOP is 3..32767, so highest available frequency is PWM_MAX_FREQ / 3. + uint16_t countertop; + nrf_pwm_clk_t base_clock; + if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } + self->frequency = frequency; - self->freq = frequency; - self->pwm->COUNTERTOP = (PWM_MAX_FREQ/frequency); - self->pwm->TASKS_SEQSTART[0] = 1; + nrf_pwm_configure(self->pwm, base_clock, NRF_PWM_MODE_UP, countertop); + // Set the duty cycle again, because it depends on COUNTERTOP, which probably changed. + // Setting the duty cycle will also do a SEQSTART. + common_hal_pulseio_pwmout_set_duty_cycle(self, self->duty_cycle); } uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { - return self->freq; + return self->frequency; } bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { - return self->variable_freq; + return self->variable_frequency; } diff --git a/ports/nrf/common-hal/pulseio/PWMOut.h b/ports/nrf/common-hal/pulseio/PWMOut.h index 9de127ac7..a4e58dc1a 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.h +++ b/ports/nrf/common-hal/pulseio/PWMOut.h @@ -27,19 +27,17 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H -#include "common-hal/microcontroller/Pin.h" - +#include "nrfx_pwm.h" #include "py/obj.h" typedef struct { mp_obj_base_t base; - const mcu_pin_obj_t *pin; NRF_PWM_Type* pwm; - - uint8_t channel; - bool variable_freq; - uint16_t duty; - uint32_t freq; + uint8_t pin_number; + uint8_t channel: 7; + bool variable_frequency: 1; + uint16_t duty_cycle; + uint32_t frequency; } pulseio_pwmout_obj_t; void pwmout_reset(void); diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index 9b7094b4e..362b8123d 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -192,7 +192,7 @@ STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t freq raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) { mp_raise_AttributeError(translate( - "PWM frequency not writeable when variable_frequency is False on " + "PWM frequency not writable when variable_frequency is False on " "construction.")); } common_hal_pulseio_pwmout_set_frequency(self, mp_obj_get_int(frequency)); -- cgit v1.2.3 From 012cc466a40366ec2f23a5b7a3090d9cb3a99fc3 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 9 Oct 2018 20:17:38 -0500 Subject: esp8266/README: comment on the specific binary SDK used --- ports/esp8266/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/esp8266/README.md b/ports/esp8266/README.md index f4dddd1ca..5f0ad8073 100644 --- a/ports/esp8266/README.md +++ b/ports/esp8266/README.md @@ -34,6 +34,14 @@ run `make` in its directory to build and install the SDK locally. Make sure to add toolchain bin directory to your PATH. Read esp-open-sdk's README for additional important information on toolchain setup. +Travis builds, including releases are actually built using a specific +esp-open-sdk binary. The location of the binary can be seen in the +`.travis.yml` in the top-level directory of CircuitPython. This may be ahead +of or behind the pfalcon repository, depending on the specific needs of +CircuitPython. If your local system is binary-compatible with Travis +(most Ubuntu and Debian based systems are), you can download the binary and +skip building it locally. + Add the external dependencies to the MicroPython repository checkout: ```bash $ git submodule update --init -- cgit v1.2.3 From ca737e6f7c6cd6ba3601230ac86bf9cce36f2da0 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 9 Oct 2018 21:23:47 -0400 Subject: Don't disable tempoarily in deinit(). --- ports/nrf/common-hal/pulseio/PWMOut.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c index 7b5741e35..5d94bab79 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.c +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -196,19 +196,20 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { nrf_gpio_cfg_default(self->pin_number); - nrf_pwm_disable(self->pwm); + NRF_PWM_Type* pwm = self->pwm; + self->pwm = NULL; - self->pwm->PSEL.OUT[self->channel] = 0xFFFFFFFF; + // Disconnect pin from channel. + pwm->PSEL.OUT[self->channel] = 0xFFFFFFFF; - // Re-enable PWM module if there is another active channel. for(int i=0; i < CHANNELS_PER_PWM; i++) { if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFF) { - nrf_pwm_enable(self->pwm); - break; + // Some channel is still being used, so don't disable. + return; } } - self->pwm = NULL; + nrf_pwm_disable(pwm); } void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty_cycle) { -- cgit v1.2.3 From 05d4b8cf50685db683dd48d7d3037da868385a0a Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Tue, 9 Oct 2018 22:50:59 -0400 Subject: Added Documentation for the serial_bytes_available attribute --- shared-bindings/supervisor/Runtime.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 1cf2a3548..27b62abd4 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -53,6 +53,12 @@ //| //| Returns the USB serial communication status (read-only). //| +//| .. attribute:: runtime.serial_bytes_available +//| +//| Returns the whether any bytes are available to read +//| on the USB serial input. Allows for polling to see whether +//| to call the built-in input() or wait. (read-only) +//| //| .. note:: //| //| SAMD: Will return ``True`` if the USB serial connection -- cgit v1.2.3 From 24e4574470c267294bdd9ffedc5df3efd52236f0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 9 Oct 2018 20:39:40 -0500 Subject: .travis.yml: dice up parallelism differently --- .travis.yml | 80 +++++++++++++++++++++++++------------------------------------ 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1237a6a6b..78fc863aa 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,36 +9,15 @@ git: # Put a representative board from each port or sub-port near the top # to determine more quickly whether that port is going to build or not. env: - - TRAVIS_TEST=unix - - TRAVIS_TEST=docs - - TRAVIS_TEST=translations - - TRAVIS_BOARD=feather_huzzah - - TRAVIS_BOARD=circuitplayground_express - - TRAVIS_BOARD=pca10056 - # The rest of the boards, in alphabetical order. - - TRAVIS_BOARD=trinket_m0 - - TRAVIS_BOARD=feather_m4_express - - TRAVIS_BOARD=grandcentral_m4_express - - TRAVIS_BOARD=arduino_zero - - TRAVIS_BOARD=circuitplayground_express_crickit - - TRAVIS_BOARD=feather_m0_adalogger - - TRAVIS_BOARD=feather_m0_basic - - TRAVIS_BOARD=feather_m0_express - - TRAVIS_BOARD=feather_m0_express_crickit - - TRAVIS_BOARD=feather_m0_rfm69 - - TRAVIS_BOARD=feather_m0_rfm9x - - TRAVIS_BOARD=feather_nrf52832 - - TRAVIS_BOARD=feather_nrf52840_express - - TRAVIS_BOARD=feather_radiofruit_zigbee - - TRAVIS_BOARD=gemma_m0 - - TRAVIS_BOARD=hallowing_m0_express - - TRAVIS_BOARD=itsybitsy_m0_express - - TRAVIS_BOARD=itsybitsy_m4_express - - TRAVIS_BOARD=metro_m0_express - - TRAVIS_BOARD=metro_m4_express - - TRAVIS_BOARD=pca10059 - - TRAVIS_BOARD=pirkey_m0 - - TRAVIS_BOARD=trellis_m4_express + - TRAVIS_TESTS="unix docs translations" + - TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056" TRAVIS_SDK=arm:nrf:esp8266 + # Group nrf builds together.. + - TRAVIS_BOARDS="pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf + # The rest of the M0/M4 boards, in arbitrary order. + - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm + - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express" TRAVIS_SDK=arm addons: artifacts: @@ -57,21 +36,28 @@ notifications: on_error: always before_script: + - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - sudo dpkg --add-architecture i386 - - ([[ -z "$TRAVIS_BOARD" || $TRAVIS_BOARD = "feather_huzzah" ]] || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) + - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) # For nrf builds - - ([[ $TRAVIS_BOARD != "feather_nrf52832" && $TRAVIS_BOARD != "feather_nrf52840_express" && $TRAVIS_BOARD != "pca10056" && $TRAVIS_BOARD != "pca10059" ]] || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh) + - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh) + # For huzzah builds - - if [[ $TRAVIS_BOARD = "feather_huzzah" ]]; then wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz; PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi + - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz)) + - if var_search "${TRAVIS_SDK-}" esp8266 ; then PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi + # For coverage testing (upgrade is used to get latest urllib3 version) - - ([[ -z "$TRAVIS_TEST" ]] || sudo apt-get install -y python3-pip) - - ([[ -z "$TRAVIS_TEST" ]] || sudo pip install --upgrade cpp-coveralls) - - ([[ $TRAVIS_TEST != "docs" ]] || sudo pip install 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark) - - ([[ $TRAVIS_TEST != "translations" ]] || sudo pip3 install polib) + - ([[ -z "$TRAVIS_TESTS" ]] || sudo apt-get install -y python3-pip) + - ([[ -z "$TRAVIS_TESTS" ]] || sudo pip install --upgrade cpp-coveralls) + - (! var_search "${TRAVIS_TESTS-}" docs || sudo pip install 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark) + - (! var_search "${TRAVIS_TESTS-}" translations || sudo pip3 install polib) + + # report some good version numbers to the buil - gcc --version - - ([[ -z "$TRAVIS_BOARD" || $TRAVIS_BOARD = "feather_huzzah" ]] || arm-none-eabi-gcc --version) + - (! var_search "${TRAVIS_SDK-}" elf || arm-none-eabi-gcc --version) + - (! var_search "${TRAVIS_SDK-}" esp8266 || xtensa-lx106-elf-gcc --version) - python3 --version script: @@ -81,13 +67,11 @@ script: - echo -en 'travis_fold:end:mpy-cross\\r' - echo 'Building Adafruit binaries' && echo -en 'travis_fold:start:adafruit-bins\\r' - - ([[ -z "$TRAVIS_BOARD" ]] || tools/build_adafruit_bins.sh) + - (for board in $TRAVIS_BOARDS; do TRAVIS_BOARD=$board tools/build_adafruit_bins.sh || exit $?; done) - echo -en 'travis_fold:end:adafruit-bins\\r' - echo 'Building unix' && echo -en 'travis_fold:start:unix\\r' - - ([[ $TRAVIS_TEST != "unix" ]] || make -C ports/unix deplibs -j2) - - ([[ $TRAVIS_TEST != "unix" ]] || make -C ports/unix -j2) - - ([[ $TRAVIS_TEST != "unix" ]] || make -C ports/unix coverage -j2) + - (! var_search "${TRAVIS_TESTS-}" unix || (make -C ports/unix deplibs -j2 && make -C ports/unix -j2 && make -C ports/unix coverage -j2)) - echo -en 'travis_fold:end:unix\\r' # run tests without coverage info @@ -96,27 +80,27 @@ script: # run tests with coverage info - echo 'Test all' && echo -en 'travis_fold:start:test_all\\r' - - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) - echo -en 'travis_fold:end:test_all\\r' - echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r' - - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) - echo -en 'travis_fold:end:test_threads\\r' - echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r' - - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) - echo -en 'travis_fold:end:test_native\\r' - (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r') - - ([[ $TRAVIS_TEST != "unix" ]] || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) - echo -en 'travis_fold:end:test_mpy\\r' - (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r') - - ([[ $TRAVIS_TEST != "docs" ]] || sphinx-build -E -W -b html . _build/html) + - (! var_search "${TRAVIS_TESTS-}" docs || sphinx-build -E -W -b html . _build/html) - echo -en 'travis_fold:end:build_docs\\r' - (echo 'Building translations' && echo -en 'travis_fold:start:build_translations\\r') - - ([[ $TRAVIS_TEST != "translations" ]] || make check-translate) + - (! var_search "${TRAVIS_TESTS-}" translations || make check-translate) - echo -en 'travis_fold:end:build_translations\\r' # run coveralls coverage analysis (try to, even if some builds/tests failed) -- cgit v1.2.3 From 0688709c4fb965b318ad40d2cab19911bd1497e8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Oct 2018 23:15:25 -0700 Subject: Move the docs next to the implementation --- shared-bindings/supervisor/Runtime.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 27b62abd4..5ba2198e1 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -53,12 +53,6 @@ //| //| Returns the USB serial communication status (read-only). //| -//| .. attribute:: runtime.serial_bytes_available -//| -//| Returns the whether any bytes are available to read -//| on the USB serial input. Allows for polling to see whether -//| to call the built-in input() or wait. (read-only) -//| //| .. note:: //| //| SAMD: Will return ``True`` if the USB serial connection @@ -86,7 +80,13 @@ const mp_obj_property_t supervisor_serial_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; -/*Added to allow for polling of USB Console*/ + +//| .. attribute:: runtime.serial_bytes_available +//| +//| Returns the whether any bytes are available to read +//| on the USB serial input. Allows for polling to see whether +//| to call the built-in input() or wait. (read-only) +//| STATIC mp_obj_t supervisor_get_serial_bytes_available(mp_obj_t self){ if (!common_hal_get_serial_bytes_available()) { return mp_const_false; -- cgit v1.2.3 From b5e26130d79d1f1b05bb83c8baf4934cb23dd747 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 10 Oct 2018 11:21:35 -0700 Subject: Support rev D for the Trellis M4 Express --- ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h | 4 ++-- ports/atmel-samd/boards/trellis_m4_express/pins.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h index fbc5300e2..05f2be0bc 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -3,7 +3,7 @@ #define CIRCUITPY_MCU_FAMILY samd51 -// This is for a purple prototype which is Rev C +// This is for Rev D #define MICROPY_HW_APA102_MOSI (&pin_PA01) #define MICROPY_HW_APA102_SCK (&pin_PA00) @@ -28,7 +28,7 @@ #include "external_flash/devices.h" #define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES W25Q128JV_SQ +#define EXTERNAL_FLASH_DEVICES GD25Q64C #include "external_flash/external_flash.h" diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c index 57abfeba4..44ffc6eaf 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/pins.c +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -15,6 +15,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB08) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_PA13) }, + // Key Grid columns { MP_OBJ_NEW_QSTR(MP_QSTR_COL0), MP_ROM_PTR(&pin_PA14) }, { MP_OBJ_NEW_QSTR(MP_QSTR_COL1), MP_ROM_PTR(&pin_PA15) }, -- cgit v1.2.3 From 1c953d44b03b9574595e07c341f8f41b2321a7e4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 10 Oct 2018 18:47:56 -0500 Subject: .travis.yml: move the esp-open-sdk SDK up a dir Otherwise, an error occurs when installing TRAVIS_SDK=esp8266 *AND* trying to do TRAVIS_TESTS=docs in the same sub-build, with an error like Warning, treated as error: .../icmp.h:77:undecodable source characters, replacing with "?" due to non-ASCII characters in some header file within the esp-open-sdk --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 78fc863aa..9985002b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -45,8 +45,8 @@ before_script: - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh) # For huzzah builds - - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar xavf xtensa-lx106-elf-standalone.tar.gz)) - - if var_search "${TRAVIS_SDK-}" esp8266 ; then PATH=$(readlink -f xtensa-lx106-elf/bin):$PATH; fi + - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar -C .. -xavf xtensa-lx106-elf-standalone.tar.gz)) + - if var_search "${TRAVIS_SDK-}" esp8266 ; then PATH=$(readlink -f ../xtensa-lx106-elf/bin):$PATH; fi # For coverage testing (upgrade is used to get latest urllib3 version) - ([[ -z "$TRAVIS_TESTS" ]] || sudo apt-get install -y python3-pip) -- cgit v1.2.3 From 6ff614caae1eacb3495b798278131295536d1f1f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 10 Oct 2018 17:43:23 -0500 Subject: .travis.yml: reorganize to squeeze out a little more speed --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9985002b5..8f4a19235 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,7 @@ git: # Put a representative board from each port or sub-port near the top # to determine more quickly whether that port is going to build or not. env: - - TRAVIS_TESTS="unix docs translations" - - TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056" TRAVIS_SDK=arm:nrf:esp8266 - # Group nrf builds together.. - - TRAVIS_BOARDS="pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf + - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 # The rest of the M0/M4 boards, in arbitrary order. - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express" TRAVIS_SDK=arm -- cgit v1.2.3 From c7629bdd5616ee4f90d7ac8521521a56264b1e4b Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 10 Oct 2018 19:24:45 -0500 Subject: .travis.yml: Comment on the rationale for the organization of the sub-builds --- .travis.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8f4a19235..65983fc92 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,22 @@ compiler: git: depth: 1 -# Put a representative board from each port or sub-port near the top -# to determine more quickly whether that port is going to build or not. +# Each item under 'env' is a separate Travis job to execute. +# They run in separate environments, so each one must take the time +# to clone the repository and submodules; to download and install SDKs, +# pip packages, and so forth. By gathering activities together in optimal +# ways, the "run time" and "total time" of the travis jobs can be minimized. +# +# Since at the time of writing Travis generally starts 5 or 6 jobs, the +# builds have been organized into 5 groups of *approximately* equal durations. +# Additionally, the jobs that need extra SDKs are also organized together. +# +# When adding new boards, take a look on the travis CI page +# https://travis-ci.org/adafruit/circuitpython to which build that installs +# that SDK is shortest and add it there. In the case of major re-organizations, +# just try to make the builds "about equal in run time" env: - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 - # The rest of the M0/M4 boards, in arbitrary order. - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm @@ -51,7 +62,7 @@ before_script: - (! var_search "${TRAVIS_TESTS-}" docs || sudo pip install 'Sphinx<1.8.0' sphinx-rtd-theme recommonmark) - (! var_search "${TRAVIS_TESTS-}" translations || sudo pip3 install polib) - # report some good version numbers to the buil + # report some good version numbers to the build - gcc --version - (! var_search "${TRAVIS_SDK-}" elf || arm-none-eabi-gcc --version) - (! var_search "${TRAVIS_SDK-}" esp8266 || xtensa-lx106-elf-gcc --version) -- cgit v1.2.3 From 8d75c3d339de7bce831490c4d12a283bf2831d43 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 13:42:26 +1100 Subject: Changed to only build wiznet for {feather|metro}_m[04]_express --- ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk | 3 +++ ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk | 3 +++ ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk | 3 +++ ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk | 3 +++ ports/atmel-samd/mpconfigport.mk | 2 -- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index d4725fdf4..e9f9b09fb 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -9,3 +9,6 @@ LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index e19a27b88..bbc5985a9 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -9,3 +9,6 @@ LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51J19A CHIP_FAMILY = samd51 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index 0388a408b..40a0092ac 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -9,3 +9,6 @@ LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 38e8a12d7..cbc89159f 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -9,3 +9,6 @@ LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51J19A CHIP_FAMILY = samd51 + +MICROPY_PY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index bc3acebb9..d5c9f2ce6 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -17,5 +17,3 @@ endif INTERNAL_LIBM = 1 -MICROPY_PY_NETWORK = 1 -MICROPY_PY_WIZNET5K = 5500 -- cgit v1.2.3 From 823ff779cacb2c940d1e9e742c66dd89223f97ad Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 14:02:18 +1100 Subject: network module c api into shared-module --- main.c | 2 +- shared-bindings/network/__init__.c | 32 +------------------- shared-bindings/network/__init__.h | 55 +--------------------------------- shared-bindings/socket/__init__.c | 2 +- shared-bindings/wiznet/__init__.c | 2 +- shared-bindings/wiznet/wiznet5k.c | 2 +- shared-module/network/__init__.c | 37 ++++++++++++++++++++++- shared-module/network/__init__.h | 60 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 102 insertions(+), 90 deletions(-) diff --git a/main.c b/main.c index f1c68d06a..c1379c571 100755 --- a/main.c +++ b/main.c @@ -55,7 +55,7 @@ #include "supervisor/serial.h" #ifdef MICROPY_PY_NETWORK -#include "shared-bindings/network/__init__.h" +#include "shared-module/network/__init__.h" #endif void do_str(const char *src, mp_parse_input_kind_t input_kind) { diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index f28d5265c..c5639b462 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -47,37 +47,7 @@ /// \module network - network configuration /// -/// This module provides network drivers and routing configuration. - -void network_module_init(void) { - mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); -} - -void network_module_deinit(void) { -} - -void network_module_register_nic(mp_obj_t nic) { - for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { - if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { - // nic already registered - return; - } - } - // nic not registered so add to list - mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic); -} - -mp_obj_t network_module_find_nic(const uint8_t *ip) { - // find a NIC that is suited to given IP address - for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { - mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; - // TODO check IP suitability here - //mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); - return nic; - } - - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); -} +/// This module provides a registry of configured NICs. STATIC mp_obj_t network_route(void) { return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)); diff --git a/shared-bindings/network/__init__.h b/shared-bindings/network/__init__.h index b3fd657b6..4fe5e75a3 100644 --- a/shared-bindings/network/__init__.h +++ b/shared-bindings/network/__init__.h @@ -26,59 +26,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H -#define MOD_NETWORK_IPADDR_BUF_SIZE (4) - -#define MOD_NETWORK_AF_INET (2) -#define MOD_NETWORK_AF_INET6 (10) - -#define MOD_NETWORK_SOCK_STREAM (1) -#define MOD_NETWORK_SOCK_DGRAM (2) -#define MOD_NETWORK_SOCK_RAW (3) - -struct _mod_network_socket_obj_t; - -typedef struct _mod_network_nic_type_t { - mp_obj_type_t base; - - // API for non-socket operations - int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out); - - // API for socket operations; return -1 on error - int (*socket)(struct _mod_network_socket_obj_t *socket, int *_errno); - void (*close)(struct _mod_network_socket_obj_t *socket); - int (*bind)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); - int (*listen)(struct _mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); - int (*accept)(struct _mod_network_socket_obj_t *socket, struct _mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); - int (*connect)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); - mp_uint_t (*send)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); - mp_uint_t (*recv)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); - mp_uint_t (*sendto)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); - mp_uint_t (*recvfrom)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); - int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); - int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); - int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); -} mod_network_nic_type_t; - -typedef struct _mod_network_socket_obj_t { - mp_obj_base_t base; - mp_obj_t nic; - mod_network_nic_type_t *nic_type; - union { - struct { - uint8_t domain; - uint8_t type; - int8_t fileno; - } u_param; - mp_uint_t u_state; - }; -} mod_network_socket_obj_t; - -extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; -extern const mod_network_nic_type_t mod_network_nic_type_cc3k; - -void network_module_init(void); -void network_module_deinit(void); -void network_module_register_nic(mp_obj_t nic); -mp_obj_t network_module_find_nic(const uint8_t *ip); +// nothing #endif // MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index 85796c5c4..f6949b4bf 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -35,7 +35,7 @@ #include "py/mperrno.h" #include "lib/netutils/netutils.h" -#include "shared-bindings/network/__init__.h" +#include "shared-module/network/__init__.h" //| :mod:`socket` --- TCP, UDP and RAW socket support //| ================================================= diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index fbdac3885..342cb1052 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -33,7 +33,7 @@ #include "py/runtime.h" #include "py/mphal.h" -#include "shared-bindings/network/__init__.h" +#include "shared-module/network/__init__.h" //| :mod:`wiznet` --- Support for WizNet hardware //| ============================================= diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index ccbd2b115..26e02fb67 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -36,7 +36,7 @@ #include "py/mphal.h" #include "lib/netutils/netutils.h" -#include "shared-bindings/network/__init__.h" +#include "shared-module/network/__init__.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/busio/SPI.h" diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c index 7e3b7fd26..6a955a0c4 100644 --- a/shared-module/network/__init__.c +++ b/shared-module/network/__init__.c @@ -24,10 +24,46 @@ * THE SOFTWARE. */ +#include "py/objlist.h" +#include "py/runtime.h" #include "py/mphal.h" +#include "py/mperrno.h" #include "shared-bindings/random/__init__.h" +// mod_network_nic_list needs to be declared in mpconfigport.h + + +void network_module_init(void) { + mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); +} + +void network_module_deinit(void) { +} + +void network_module_register_nic(mp_obj_t nic) { + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { + // nic already registered + return; + } + } + // nic not registered so add to list + mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic); +} + +mp_obj_t network_module_find_nic(const uint8_t *ip) { + // find a NIC that is suited to given IP address + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + // TODO check IP suitability here + //mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + return nic; + } + + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); +} + void network_module_create_random_mac_address(uint8_t *mac) { uint32_t rb1 = shared_modules_random_getrandbits(24); uint32_t rb2 = shared_modules_random_getrandbits(24); @@ -40,4 +76,3 @@ void network_module_create_random_mac_address(uint8_t *mac) { mac[4] = (uint8_t)(rb2 >> 8); mac[5] = (uint8_t)(rb2); } - diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h index 13f800fb0..ce5b4e6d3 100644 --- a/shared-module/network/__init__.h +++ b/shared-module/network/__init__.h @@ -3,6 +3,7 @@ * * The MIT License (MIT) * + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2018 Nick Moore * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -26,3 +27,62 @@ void network_module_create_random_mac_address(uint8_t *mac); +#ifndef MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H + +#define MOD_NETWORK_IPADDR_BUF_SIZE (4) + +#define MOD_NETWORK_AF_INET (2) +#define MOD_NETWORK_AF_INET6 (10) + +#define MOD_NETWORK_SOCK_STREAM (1) +#define MOD_NETWORK_SOCK_DGRAM (2) +#define MOD_NETWORK_SOCK_RAW (3) + +struct _mod_network_socket_obj_t; + +typedef struct _mod_network_nic_type_t { + mp_obj_type_t base; + + // API for non-socket operations + int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out); + + // API for socket operations; return -1 on error + int (*socket)(struct _mod_network_socket_obj_t *socket, int *_errno); + void (*close)(struct _mod_network_socket_obj_t *socket); + int (*bind)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + int (*listen)(struct _mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); + int (*accept)(struct _mod_network_socket_obj_t *socket, struct _mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); + int (*connect)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*send)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*recv)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*sendto)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*recvfrom)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); + int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); + int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); + int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +} mod_network_nic_type_t; + +typedef struct _mod_network_socket_obj_t { + mp_obj_base_t base; + mp_obj_t nic; + mod_network_nic_type_t *nic_type; + union { + struct { + uint8_t domain; + uint8_t type; + int8_t fileno; + } u_param; + mp_uint_t u_state; + }; +} mod_network_socket_obj_t; + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; +extern const mod_network_nic_type_t mod_network_nic_type_cc3k; + +void network_module_init(void); +void network_module_deinit(void); +void network_module_register_nic(mp_obj_t nic); +mp_obj_t network_module_find_nic(const uint8_t *ip); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H -- cgit v1.2.3 From 09e6127435e5afb5c9caa9298d68176679cc51ce Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 14:12:47 +1100 Subject: update translations? --- locale/circuitpython.pot | 40 ++++++++++++++++++++-------------------- locale/de_DE.po | 40 ++++++++++++++++++++-------------------- locale/en_US.po | 40 ++++++++++++++++++++-------------------- locale/es.po | 40 ++++++++++++++++++++-------------------- locale/fil.po | 41 ++++++++++++++++++++--------------------- locale/fr.po | 41 +++++++++++++++++++++-------------------- locale/pt_BR.po | 48 ++++++++++++++++++++++++------------------------ 7 files changed, 145 insertions(+), 145 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 232ad7c46..c47f57cf3 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -151,70 +151,70 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr "" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "" -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "" -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2153,6 +2149,10 @@ msgstr "" msgid "Stream missing readinto() or write() method." msgstr "" +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 790b23442..2f4cf7cef 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "ungültige argumente" msgid "script compilation not supported" msgstr "kompilieren von Skripten ist nicht unterstützt" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr " Ausgabe:\n" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,45 +163,45 @@ msgstr "" "Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " "auszuführen oder verbinde dich mit der REPL um zu deaktivieren.\n" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Sicherheitsmodus aktiv! Automatisches Neuladen ist deaktiviert.\n" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "Automatisches Neuladen ist deaktiviert.\n" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "WARNUNG: Der Dateiname deines codes hat zwei Dateityperweiterungen\n" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "Du hast das Starten im Sicherheitsmodus ausgelöst durch " -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "Zum beenden bitte resete das board ohne " -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "Sicherheitsmodus aktive, etwas wirklich schlechtes ist passiert.\n" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "CircuitPython ist abgestürzt. Ups!\n" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -209,7 +209,7 @@ msgstr "" "Die Stromversorgung des Mikrocontrollers ist eingebrochen. Stelle sicher," "dass deine Stromversorgung\n" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -217,13 +217,13 @@ msgstr "" "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach " "demsicheren Auswerfen von CIRCUITPY.)\n" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Drücke eine Taste um dich mit der REPL zu verbinden. Drücke Strg-D zum neu " "laden" -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "weicher reboot\n" @@ -713,10 +713,6 @@ msgstr "Alle timer werden benutzt" msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2167,6 +2163,10 @@ msgstr "" msgid "Stream missing readinto() or write() method." msgstr "" +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index 6e576f150..41449daa7 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,70 +151,70 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr "" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "" -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "" -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2153,6 +2149,10 @@ msgstr "" msgid "Stream missing readinto() or write() method." msgstr "" +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "" diff --git a/locale/es.po b/locale/es.po index 2ac904943..2ce851769 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -153,11 +153,11 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "script de compilación no soportado" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr " salida:\n" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 #, fuzzy msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " @@ -166,57 +166,57 @@ msgstr "" "Auto-reload habilitado. Simplemente guarda los archivos via USB para " "ejecutarlos o entra REPL para desabilitarlos.\n" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Ejecutando en modo seguro! Auto-recarga esta deshabilitado.\n" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "Auto-reload deshabilitado.\n" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "Solicitaste iniciar en modo seguro con " -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "Para salir, por favor reinicia la tarjeta sin " -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Estás ejecutando en modo seguro, lo cual significa que algo realmente malo " "ha sucedido.\n" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" "Parece que nuestro código del núcleo CircuitPython dejó de funcionar. " "Whoops!\n" -#: main.c:252 +#: main.c:262 #, fuzzy msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Por favor registra un problema aquí con los contenidos de tu unidad de " "almacenamiento CIRCUITPY:\n" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -224,12 +224,12 @@ msgstr "" "suficiente poder para todo el circuito y pulsa reset (después de expulsar " "CIRCUITPY).\n" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar." -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "reinicio suave\n" @@ -719,10 +719,6 @@ msgstr "Todos los timers están siendo utilizados" msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2200,6 +2196,10 @@ msgstr "" msgid "Stream missing readinto() or write() method." msgstr "" +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "" diff --git a/locale/fil.po b/locale/fil.po index 7c8c4fdfe..20a820445 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -151,11 +151,11 @@ msgstr "mali ang mga argumento" msgid "script compilation not supported" msgstr "script kompilasyon hindi supportado" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr " output:\n" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,48 +163,48 @@ msgstr "" "Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB " "para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Tumatakbo sa safe mode! Awtomatikong pag re-reload ay OFF.\n" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "Awtomatikong pag re-reload ay OFF.\n" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "Para lumabas, paki-reset ang board na wala ang " -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Ikaw ay tumatakbo sa safe mode, ang ibig sabihin nito ay may masamang " "nangyari.\n" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " "drive:\n" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -212,7 +212,7 @@ msgstr "" "Ang kapangyarihan ng mikrokontroller ay bumaba. Mangyaring suriin ang power " "supply \n" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -220,13 +220,13 @@ msgstr "" "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang reset " "(pagkatapos i-eject ang CIRCUITPY).\n" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Pindutin ang anumang key upang ipasok ang REPL. Gamitin ang CTRL-D upang i-" "reload." -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "malambot na reboot\n" @@ -719,10 +719,6 @@ msgstr "Lahat ng timer ginagamit" msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -743,7 +739,6 @@ msgstr "hindi sinusuportahan ang bytes > 8 bits" #: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 #: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 #: ports/nrf/common-hal/busio/UART.c:364 -#, fuzzy msgid "busio.UART not available" msgstr "" @@ -2210,6 +2205,10 @@ msgstr "Mali ang run mode." msgid "Stream missing readinto() or write() method." msgstr "Stream kulang ng readinto() o write() method." +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "Slice at value iba't ibang haba." diff --git a/locale/fr.po b/locale/fr.po index 04d7a0665..f92a98200 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -150,11 +150,11 @@ msgstr "arguments invalides" msgid "script compilation not supported" msgstr "compilation du script non supporté" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr " sortie:\n" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -162,46 +162,46 @@ msgstr "" "Auto-chargement activé. Copiez simplement les fichiers en USB pour les " "lancer ou entrez sur REPL pour le désactiver.\n" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Mode sans-échec. Auto-rechargement désactivé.\n" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "Auto-rechargement désactivé.\n" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "Mode sans-échec! Le code sauvegardé ne s'éxecute pas.\n" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "Vous avez demandé à démarrer en mode sans-échec par " -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "Pour quitter, redémarrez la carte SVP sans " -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Vous êtes en mode sans-échec ce qui signifie que quelque chose demauvais est " "arrivé.\n" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -209,7 +209,7 @@ msgstr "" "L'alimentation du microcontroleur a chuté. Merci de vérifier que votre " "alimentation fournit\n" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -217,11 +217,11 @@ msgstr "" "assez de puissance pour l'ensemble du circuit et appuyez sur 'reset' (après " "avoir éjecter CIRCUITPY).\n" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "redémarrage logiciel\n" @@ -715,10 +715,6 @@ msgstr "Tous les timers sont utilisés" msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2203,6 +2199,11 @@ msgstr "Mode de lancement invalide" msgid "Stream missing readinto() or write() method." msgstr "Il manque une méthode readinto() ou write() au flux." +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +#, fuzzy +msgid "no available NIC" +msgstr "busio.UART n'est pas disponible" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "Slice et valeur de tailles différentes" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index d6b283c9f..3245f5aa0 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-03 23:15+0700\n" +"POT-Creation-Date: 2018-10-09 23:01+1100\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,70 +151,70 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "compilação de script não suportada" -#: main.c:143 +#: main.c:153 msgid " output:\n" msgstr " saída:\n" -#: main.c:157 main.c:230 +#: main.c:167 main.c:240 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:159 +#: main.c:169 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" -#: main.c:161 main.c:232 +#: main.c:171 main.c:242 msgid "Auto-reload is off.\n" msgstr "A atualização automática está desligada.\n" -#: main.c:175 +#: main.c:185 msgid "Running in safe mode! Not running saved code.\n" msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" -#: main.c:191 +#: main.c:201 msgid "WARNING: Your code filename has two extensions\n" msgstr "AVISO: Seu arquivo de código tem duas extensões\n" -#: main.c:239 +#: main.c:249 msgid "You requested starting safe mode by " msgstr "Você solicitou o início do modo de segurança" -#: main.c:242 +#: main.c:252 msgid "To exit, please reset the board without " msgstr "Para sair, por favor, reinicie a placa sem " -#: main.c:249 +#: main.c:259 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:251 +#: main.c:261 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:252 +#: main.c:262 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:255 +#: main.c:265 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:256 +#: main.c:266 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:260 +#: main.c:270 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:416 +#: main.c:426 msgid "soft reboot\n" msgstr "" @@ -702,10 +702,6 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:176 -msgid "Baud rate too high for this SPI peripheral" -msgstr "" - #: ports/nrf/common-hal/busio/UART.c:48 #, c-format msgid "error = 0x%08lX" @@ -2009,19 +2005,19 @@ msgstr "" msgid "Buffer must be at least length 1" msgstr "" -#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:168 +#: shared-bindings/bitbangio/SPI.c:151 shared-bindings/busio/SPI.c:175 msgid "Invalid polarity" msgstr "" -#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:172 +#: shared-bindings/bitbangio/SPI.c:155 shared-bindings/busio/SPI.c:179 msgid "Invalid phase" msgstr "Fase Inválida" -#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:176 +#: shared-bindings/bitbangio/SPI.c:159 shared-bindings/busio/SPI.c:183 msgid "Invalid number of bits" msgstr "Número inválido de bits" -#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:341 +#: shared-bindings/bitbangio/SPI.c:284 shared-bindings/busio/SPI.c:348 msgid "buffer slices must be of equal length" msgstr "" @@ -2155,6 +2151,10 @@ msgstr "" msgid "Stream missing readinto() or write() method." msgstr "" +#: shared-bindings/network/__init__.c:79 shared-bindings/socket/__init__.c:428 +msgid "no available NIC" +msgstr "" + #: shared-bindings/nvm/ByteArray.c:99 msgid "Slice and value different lengths." msgstr "" -- cgit v1.2.3 From bb239052ea5bf710da66db032de94e5760040090 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 15:05:25 +1100 Subject: Split wiznet driver into shared-bindings vs shared-module --- shared-bindings/wiznet/wiznet5k.c | 415 +------------------------------------- shared-module/wiznet/wiznet5k.c | 413 +++++++++++++++++++++++++++++++++++++ shared-module/wiznet/wiznet5k.h | 63 ++++++ 3 files changed, 480 insertions(+), 411 deletions(-) create mode 100644 shared-module/wiznet/wiznet5k.h diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 26e02fb67..b407dc5cb 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -36,336 +36,15 @@ #include "py/mphal.h" #include "lib/netutils/netutils.h" -#include "shared-module/network/__init__.h" +#if MICROPY_PY_WIZNET5K + #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/busio/SPI.h" #include "shared-module/network/__init__.h" +#include "shared-module/wiznet/wiznet5k.h" -#if MICROPY_PY_WIZNET5K - -#include "ethernet/wizchip_conf.h" -#include "ethernet/socket.h" -#include "internet/dns/dns.h" -#include "internet/dhcp/dhcp.h" - -//| .. currentmodule:: wiznet -//| -//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface -//| =============================================================== -//| -//| .. class:: WIZNET5K(spi, cs, rst) -//| -//| Create a new WIZNET5500 interface using the specified pins -//| - -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - busio_spi_obj_t *spi; - digitalio_digitalinout_obj_t cs; - digitalio_digitalinout_obj_t rst; - uint8_t socket_used; -} wiznet5k_obj_t; - -STATIC wiznet5k_obj_t wiznet5k_obj; - -STATIC void wiz_cris_enter(void) { - wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); -} - -STATIC void wiz_cris_exit(void) { - MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); -} - -STATIC void wiz_cs_select(void) { - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); -} - -STATIC void wiz_cs_deselect(void) { - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); -} - -STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { - (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); -} - -STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { - (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); -} - -STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { - uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; - uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); - DNS_init(0, buf); - mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); - m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); - if (ret == 1) { - // success - return 0; - } else { - // failure - return -2; - } -} - -STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { - if (socket->u_param.domain != MOD_NETWORK_AF_INET) { - *_errno = MP_EAFNOSUPPORT; - return -1; - } - - switch (socket->u_param.type) { - case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; - case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; - default: *_errno = MP_EINVAL; return -1; - } - - if (socket->u_param.fileno == -1) { - // get first unused socket number - for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { - if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { - wiznet5k_obj.socket_used |= (1 << sn); - socket->u_param.fileno = sn; - break; - } - } - if (socket->u_param.fileno == -1) { - // too many open sockets - *_errno = MP_EMFILE; - return -1; - } - } - - // WIZNET does not have a concept of pure "open socket". You need to know - // if it's a server or client at the time of creation of the socket. - // So, we defer the open until we know what kind of socket we want. - - // use "domain" to indicate that this socket has not yet been opened - socket->u_param.domain = 0; - - return 0; -} - -STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { - uint8_t sn = (uint8_t)socket->u_param.fileno; - if (sn < _WIZCHIP_SOCK_NUM_) { - wiznet5k_obj.socket_used &= ~(1 << sn); - WIZCHIP_EXPORT(close)(sn); - } -} - -STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // open the socket in server mode (if port != 0) - mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // indicate that this socket has been opened - socket->u_param.domain = 1; - - // success - return 0; -} - -STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { - mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return 0; -} - -STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { - for (;;) { - int sr = getSn_SR((uint8_t)socket->u_param.fileno); - if (sr == SOCK_ESTABLISHED) { - socket2->u_param = socket->u_param; - getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); - *port = getSn_PORT(socket2->u_param.fileno); - - // WIZnet turns the listening socket into the client socket, so we - // need to re-bind and re-listen on another socket for the server. - // TODO handle errors, especially no-more-sockets error - socket->u_param.domain = MOD_NETWORK_AF_INET; - socket->u_param.fileno = -1; - int _errno2; - if (wiznet5k_socket_socket(socket, &_errno2) != 0) { - //printf("(bad resocket %d)\n", _errno2); - } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { - //printf("(bad rebind %d)\n", _errno2); - } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { - //printf("(bad relisten %d)\n", _errno2); - } - - return 0; - } - if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { - wiznet5k_socket_close(socket); - *_errno = MP_ENOTCONN; // ?? - return -1; - } - mp_hal_delay_ms(1); - } -} - -STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { - // use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - - // now connect - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - - // success - return 0; -} - -STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); - MP_THREAD_GIL_ENTER(); - - // TODO convert Wiz errno's to POSIX ones - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { - if (socket->u_param.domain == 0) { - // socket not opened; use "bind" function to open the socket in client mode - if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { - return -1; - } - } - - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); - MP_THREAD_GIL_ENTER(); - - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { - uint16_t port2; - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); - MP_THREAD_GIL_ENTER(); - *port = port2; - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; - } - return ret; -} - -STATIC int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; -} - -STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; - - /* - if (timeout_ms == 0) { - // set non-blocking mode - uint8_t arg = SOCK_IO_NONBLOCK; - WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); - } - */ -} - -STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { - if (request == MP_STREAM_POLL) { - int ret = 0; - if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { - ret |= MP_STREAM_POLL_RD; - } - if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { - ret |= MP_STREAM_POLL_WR; - } - return ret; - } else { - *_errno = MP_EINVAL; - return MP_STREAM_ERROR; - } -} - -#if 0 -STATIC void wiznet5k_socket_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - wiznet5k_socket_obj_t *self = self_in; - print(env, "", self->sn, getSn_MR(self->sn)); -} - -STATIC mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in) { - mp_int_t ret = WIZCHIP_EXPORT(disconnect)(self->sn); - return 0; -} -#endif - -static void wiznet5k_try_dhcp(void) { - DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; - - // Set up the socket to listen on UDP 68 before calling DHCP_init - WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); - DHCP_init(0, dhcp_buf); - - // try a few times for DHCP ... XXX this should be asynchronous. - for (int i=0; i<10; i++) { - DHCP_time_handler(); - int dhcp_state = DHCP_run(); - if (dhcp_state == DHCP_IP_LEASED || dhcp_state == DHCP_IP_CHANGED) break; - mp_hal_delay_ms(1000); - } - DHCP_stop(); - WIZCHIP_EXPORT(close)(0); -} - -/******************************************************************************/ -// MicroPython bindings /// \classmethod \constructor(spi, pin_cs, pin_rst) /// Create and return a WIZNET5K object. @@ -373,93 +52,8 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size // check arguments mp_arg_check_num(n_args, n_kw, 3, 3, false); - // init the wiznet5k object - wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; - wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = MP_OBJ_TO_PTR(args[0]); - common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, args[1]); - common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, args[2]); - wiznet5k_obj.socket_used = 0; - - /*!< SPI configuration */ - // XXX probably should check if the provided SPI is already configured, and - // if so skip configuration? - - common_hal_busio_spi_configure(wiznet5k_obj.spi, - 10000000, // BAUDRATE 10MHz - 1, // HIGH POLARITY - 1, // SECOND PHASE TRANSITION - 8 // 8 BITS - ); - - common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); - common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL); - - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); - mp_hal_delay_us(10); // datasheet says 2us - common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); - mp_hal_delay_ms(160); // datasheet says 150ms - - reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); - reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); - reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); - - // 2k buffer for each socket - uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; - ctlwizchip(CW_INIT_WIZCHIP, sn_size); - - wiz_NetInfo netinfo = { - .dhcp = NETINFO_DHCP, - }; - network_module_create_random_mac_address(netinfo.mac); - ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); - - // seems we need a small delay after init - mp_hal_delay_ms(250); - - wiznet5k_try_dhcp(); - - // register with network module - network_module_register_nic(&wiznet5k_obj); - - // return wiznet5k object - return &wiznet5k_obj; -} - -/// \method regs() -/// Dump WIZNET5K registers. -STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) { - //wiznet5k_obj_t *self = self_in; - printf("Wiz CREG:"); - for (int i = 0; i < 0x50; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_WIZNET5K == 5200 - uint32_t reg = i; - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - for (int sn = 0; sn < 4; ++sn) { - printf("\nWiz SREG[%d]:", sn); - for (int i = 0; i < 0x30; ++i) { - if (i % 16 == 0) { - printf("\n %04x:", i); - } - #if MICROPY_PY_WIZNET5K == 5200 - uint32_t reg = WIZCHIP_SREG_ADDR(sn, i); - #else - uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3; - #endif - printf(" %02x", WIZCHIP_READ(reg)); - } - } - printf("\n"); - return mp_const_none; + return wiznet5k_create(args[0], args[1], args[2]); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { (void)self_in; @@ -507,7 +101,6 @@ STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, }; diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index e69de29bb..1ae73a515 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -0,0 +1,413 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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 +#include +#include + +#include "py/objlist.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "lib/netutils/netutils.h" + +#if MICROPY_PY_WIZNET5K + +#include "shared-module/network/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/busio/SPI.h" + +#include "shared-module/network/__init__.h" + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" +#include "internet/dhcp/dhcp.h" + +//| .. currentmodule:: wiznet +//| +//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface +//| =============================================================== +//| +//| .. class:: WIZNET5K(spi, cs, rst) +//| +//| Create a new WIZNET5500 interface using the specified pins +//| + +typedef struct _wiznet5k_obj_t { + mp_obj_base_t base; + mp_uint_t cris_state; + busio_spi_obj_t *spi; + digitalio_digitalinout_obj_t cs; + digitalio_digitalinout_obj_t rst; + uint8_t socket_used; +} wiznet5k_obj_t; + +static wiznet5k_obj_t wiznet5k_obj; + +STATIC wiznet5k_obj_t wiznet5k_obj; + +STATIC void wiz_cris_enter(void) { + wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); +} + +STATIC void wiz_cris_exit(void) { + MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); +} + +STATIC void wiz_cs_select(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); +} + +STATIC void wiz_cs_deselect(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); +} + +STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); +} + +STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); +} + +int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; + uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); + DNS_init(0, buf); + mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); + m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + if (ret == 1) { + // success + return 0; + } else { + // failure + return -2; + } +} + +int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { + if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + *_errno = MP_EAFNOSUPPORT; + return -1; + } + + switch (socket->u_param.type) { + case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; + case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; + default: *_errno = MP_EINVAL; return -1; + } + + if (socket->u_param.fileno == -1) { + // get first unused socket number + for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { + wiznet5k_obj.socket_used |= (1 << sn); + socket->u_param.fileno = sn; + break; + } + } + if (socket->u_param.fileno == -1) { + // too many open sockets + *_errno = MP_EMFILE; + return -1; + } + } + + // WIZNET does not have a concept of pure "open socket". You need to know + // if it's a server or client at the time of creation of the socket. + // So, we defer the open until we know what kind of socket we want. + + // use "domain" to indicate that this socket has not yet been opened + socket->u_param.domain = 0; + + return 0; +} + +void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { + uint8_t sn = (uint8_t)socket->u_param.fileno; + if (sn < _WIZCHIP_SOCK_NUM_) { + wiznet5k_obj.socket_used &= ~(1 << sn); + WIZCHIP_EXPORT(close)(sn); + } +} + +int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // open the socket in server mode (if port != 0) + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // indicate that this socket has been opened + socket->u_param.domain = 1; + + // success + return 0; +} + +int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { + mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return 0; +} + +int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { + for (;;) { + int sr = getSn_SR((uint8_t)socket->u_param.fileno); + if (sr == SOCK_ESTABLISHED) { + socket2->u_param = socket->u_param; + getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); + *port = getSn_PORT(socket2->u_param.fileno); + + // WIZnet turns the listening socket into the client socket, so we + // need to re-bind and re-listen on another socket for the server. + // TODO handle errors, especially no-more-sockets error + socket->u_param.domain = MOD_NETWORK_AF_INET; + socket->u_param.fileno = -1; + int _errno2; + if (wiznet5k_socket_socket(socket, &_errno2) != 0) { + //printf("(bad resocket %d)\n", _errno2); + } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { + //printf("(bad rebind %d)\n", _errno2); + } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { + //printf("(bad relisten %d)\n", _errno2); + } + + return 0; + } + if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { + wiznet5k_socket_close(socket); + *_errno = MP_ENOTCONN; // ?? + return -1; + } + mp_hal_delay_ms(1); + } +} + +int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + + // now connect + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // success + return 0; +} + +mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { + if (socket->u_param.domain == 0) { + // socket not opened; use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + } + + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { + uint16_t port2; + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); + MP_THREAD_GIL_ENTER(); + *port = port2; + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; +} + +int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; + + /* + if (timeout_ms == 0) { + // set non-blocking mode + uint8_t arg = SOCK_IO_NONBLOCK; + WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); + } + */ +} + +int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + if (request == MP_STREAM_POLL) { + int ret = 0; + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_RD; + } + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_WR; + } + return ret; + } else { + *_errno = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +static void wiznet5k_try_dhcp(void) { + DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; + + // Set up the socket to listen on UDP 68 before calling DHCP_init + WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); + DHCP_init(0, dhcp_buf); + + // try a few times for DHCP ... XXX this should be asynchronous. + for (int i=0; i<10; i++) { + DHCP_time_handler(); + int dhcp_state = DHCP_run(); + if (dhcp_state == DHCP_IP_LEASED || dhcp_state == DHCP_IP_CHANGED) break; + mp_hal_delay_ms(1000); + } + DHCP_stop(); + WIZCHIP_EXPORT(close)(0); +} + +/// Create and return a WIZNET5K object. +mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { + + // init the wiznet5k object + wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; + wiznet5k_obj.cris_state = 0; + wiznet5k_obj.spi = MP_OBJ_TO_PTR(spi_in); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, cs_in); + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, rst_in); + wiznet5k_obj.socket_used = 0; + + /*!< SPI configuration */ + // XXX probably should check if the provided SPI is already configured, and + // if so skip configuration? + + common_hal_busio_spi_configure(wiznet5k_obj.spi, + 10000000, // BAUDRATE 10MHz + 1, // HIGH POLARITY + 1, // SECOND PHASE TRANSITION + 8 // 8 BITS + ); + + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL); + + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); + mp_hal_delay_us(10); // datasheet says 2us + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); + mp_hal_delay_ms(160); // datasheet says 150ms + + reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); + reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); + reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); + + // 2k buffer for each socket + uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + ctlwizchip(CW_INIT_WIZCHIP, sn_size); + + wiz_NetInfo netinfo = { + .dhcp = NETINFO_DHCP, + }; + network_module_create_random_mac_address(netinfo.mac); + ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); + + // seems we need a small delay after init + mp_hal_delay_ms(250); + + wiznet5k_try_dhcp(); + + // register with network module + network_module_register_nic(&wiznet5k_obj); + + // return wiznet5k object + return &wiznet5k_obj; +} + +#endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h new file mode 100644 index 000000000..f3e3dcfe1 --- /dev/null +++ b/shared-module/wiznet/wiznet5k.h @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H +#define MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" +#include "internet/dhcp/dhcp.h" + +typedef struct _wiznet5k_obj_t { + mp_obj_base_t base; + mp_uint_t cris_state; + busio_spi_obj_t *spi; + digitalio_digitalinout_obj_t cs; + digitalio_digitalinout_obj_t rst; + uint8_t socket_used; +} wiznet5k_obj_t; + +int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip); +int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno); +void wiznet5k_socket_close(mod_network_socket_obj_t *socket); +int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); +int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); +int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); +int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); +mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); +mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); +mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); +mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); +int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); +int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); +int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); +mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H -- cgit v1.2.3 From a580e870c385c9cdd698f04eb6a6ee34aff2f5ab Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 16:27:43 +1100 Subject: update locale info --- locale/circuitpython.pot | 2 +- locale/fr.po | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index fb6fa9ba1..be88a16f5 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:17+1100\n" +"POT-Creation-Date: 2018-10-11 16:27+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr.po b/locale/fr.po index a7b779ddb..d6f572069 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:17+1100\n" +"POT-Creation-Date: 2018-10-11 16:27+1100\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2522,10 +2522,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" - #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" -- cgit v1.2.3 From a4a0cf826b9d39f14317e6021ac2a5c08d575fbd Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 17:02:29 +1100 Subject: fix doc comments, translations again --- locale/circuitpython.pot | 2 +- locale/fr.po | 10 +++++----- shared-bindings/wiznet/wiznet5k.c | 11 +++++++++-- shared-module/wiznet/wiznet5k.c | 10 ---------- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index be88a16f5..6c2a10891 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 16:27+1100\n" +"POT-Creation-Date: 2018-10-11 17:02+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr.po b/locale/fr.po index d6f572069..1658d90ce 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 16:27+1100\n" +"POT-Creation-Date: 2018-10-11 17:02+1100\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2522,10 +2522,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "'len' doit être un multiple de 4" - #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "la palette doit être longue de 32 octets" + +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "'len' doit être un multiple de 4" diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index b407dc5cb..32f100969 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -45,9 +45,16 @@ #include "shared-module/network/__init__.h" #include "shared-module/wiznet/wiznet5k.h" +//| .. currentmodule:: wiznet +//| +//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface +//| =============================================================== +//| +//| .. class:: WIZNET5K(spi, cs, rst) +//| +//| Create a new WIZNET5500 interface using the specified pins +//| -/// \classmethod \constructor(spi, pin_cs, pin_rst) -/// Create and return a WIZNET5K object. STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 3, 3, false); diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 1ae73a515..5c311bf49 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -50,16 +50,6 @@ #include "internet/dns/dns.h" #include "internet/dhcp/dhcp.h" -//| .. currentmodule:: wiznet -//| -//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface -//| =============================================================== -//| -//| .. class:: WIZNET5K(spi, cs, rst) -//| -//| Create a new WIZNET5500 interface using the specified pins -//| - typedef struct _wiznet5k_obj_t { mp_obj_base_t base; mp_uint_t cris_state; -- cgit v1.2.3 From 5bb12793a0c978fc731e29d0dee00cdf86b8234f Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 11 Oct 2018 22:19:46 +1100 Subject: update documentation and translations again --- docs/library/usocket.rst | 6 +- locale/circuitpython.pot | 4 +- locale/de_DE.po | 4 +- locale/en_US.po | 4 +- locale/es.po | 4 +- locale/fil.po | 4 +- locale/fr.po | 12 ++-- locale/it_IT.po | 4 +- locale/pt_BR.po | 4 +- shared-bindings/network/__init__.c | 17 ++++-- shared-bindings/socket/__init__.c | 122 +++++++++++++++++++++++++++++++------ shared-bindings/wiznet/__init__.c | 2 +- shared-bindings/wiznet/wiznet5k.c | 17 +++++- 13 files changed, 154 insertions(+), 50 deletions(-) diff --git a/docs/library/usocket.rst b/docs/library/usocket.rst index 2751db6c4..2115085a3 100644 --- a/docs/library/usocket.rst +++ b/docs/library/usocket.rst @@ -138,16 +138,16 @@ Constants Note that you don't need to specify these in a call to `usocket.socket()`, because `SOCK_STREAM` socket type automatically selects `IPPROTO_TCP`, and `SOCK_DGRAM` - `IPPROTO_UDP`. Thus, the only real use of these constants - is as an argument to `setsockopt()`. + is as an argument to `usocket.socket.setsockopt()`. .. data:: usocket.SOL_* - Socket option levels (an argument to `setsockopt()`). The exact + Socket option levels (an argument to `usocket.socket.setsockopt()`). The exact inventory depends on a ``MicroPython port``. .. data:: usocket.SO_* - Socket options (an argument to `setsockopt()`). The exact + Socket options (an argument to `usocket.socket.setsockopt()`). The exact inventory depends on a ``MicroPython port``. Constants specific to WiPy: diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 6c2a10891..8fc817849 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 17:02+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -2292,7 +2292,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 1672ef178..3f7b22702 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:16+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -2311,7 +2311,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index d26568310..8bc73ad5c 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:16+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -2292,7 +2292,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/locale/es.po b/locale/es.po index df8803425..ee97a192c 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:16+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -2340,7 +2340,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index 6fe9adfe6..e432da717 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:16+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -2358,7 +2358,7 @@ msgstr "Hindi supportado ang RTC sa board na ito" msgid "RTC calibration is not supported on this board" msgstr "RTC calibration ay hindi supportado ng board na ito" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 1658d90ce..51d999a2c 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 17:02+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2354,7 +2354,7 @@ msgstr "RTC non supportée sur cette carte" msgid "RTC calibration is not supported on this board" msgstr "calibration de la RTC non supportée sur cette carte" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 #, fuzzy msgid "no available NIC" msgstr "busio.UART n'est pas disponible" @@ -2522,10 +2522,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" - #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" diff --git a/locale/it_IT.po b/locale/it_IT.po index 907e9f8d1..b093a949a 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:15+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -2344,7 +2344,7 @@ msgstr "RTC non supportato su questa scheda" msgid "RTC calibration is not supported on this board" msgstr "calibrazione RTC non supportata su questa scheda" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 #, fuzzy msgid "no available NIC" msgstr "busio.UART non ancora implementato" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e499821e1..c54983951 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-11 14:17+1100\n" +"POT-Creation-Date: 2018-10-11 22:08+1100\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -2299,7 +2299,7 @@ msgstr "O RTC não é suportado nesta placa" msgid "RTC calibration is not supported on this board" msgstr "A calibração RTC não é suportada nesta placa" -#: shared-bindings/socket/__init__.c:428 shared-module/network/__init__.c:64 +#: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:64 msgid "no available NIC" msgstr "" diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index c5639b462..69f8bea60 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -36,18 +36,23 @@ #include "shared-bindings/network/__init__.h" +#if MICROPY_PY_NETWORK + //| :mod:`network` --- Network Interface Management //| =============================================== //| //| .. module:: network //| :synopsis: Network Interface Management //| :platform: SAMD - -#if MICROPY_PY_NETWORK - -/// \module network - network configuration -/// -/// This module provides a registry of configured NICs. +//| +//| This module provides a registry of configured NICs. +//| It is used by the 'socket' module to look up a suitable +//| NIC when a socket is created. +//| +//| .. function:: route +//| +//| Returns a list of all configured NICs. +//| STATIC mp_obj_t network_route(void) { return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)); diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index f6949b4bf..d860c40c8 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -44,11 +44,22 @@ //| :synopsis: TCP, UDP and RAW sockets //| :platform: SAMD21, SAMD51 //| -//| XXX TODO Write Docs. +//| Create TCP, UDP and RAW sockets for communicating over the Internet. +//| STATIC const mp_obj_type_t socket_type; -// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) +//| .. currentmodule:: socket +//| +//| .. class:: socket(family, type, proto, ...) +//| +//| Create a new socket +//| +//| :param ~int family: AF_INET or AF_INET6 +//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW +//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored) +//| + STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 4, false); @@ -87,7 +98,13 @@ STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { } } -// method socket.bind(address) +//| .. method:: bind(address) +//| +//| Bind a socket to an address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -108,7 +125,13 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); -// method socket.listen(backlog) +//| .. method:: listen(backlog) +//| +//| Set socket to listen for incoming connections +//| +//| :param ~int backlog: length of backlog queue for waiting connetions +//| + STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -127,7 +150,13 @@ STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); -// method socket.accept() +//| .. method:: accept() +//| +//| Accept a connection on a listening socket of type SOCK_STREAM, +//| creating a new socket of type SOCK_STREAM. +//| Returns a tuple of (new_socket, remote_address) +//| + STATIC mp_obj_t socket_accept(mp_obj_t self_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -159,7 +188,13 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); -// method socket.connect(address) +//| .. method:: connect(address) +//| +//| Connect a socket to a remote address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -180,7 +215,14 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); -// method socket.send(bytes) +//| .. method:: send(bytes) +//| +//| Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| :param ~bytes bytes: some bytes to send +//| + STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { @@ -198,7 +240,14 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); -// method socket.recv(bufsize) +//| .. method:: recv(bufsize) +//| +//| Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| Returns a bytes() of length <= bufsize +//| +//| :param ~int bufsize: maximum number of bytes to receive + STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { @@ -221,7 +270,15 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); -// method socket.sendto(bytes, address) +//| .. method:: sendto(bytes, address) +//| +//| Send some bytes to a specific address. +//| Suits sockets of type SOCK_DGRAM +//| +//| :param ~bytes bytes: some bytes to send +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -247,7 +304,18 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_ } STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); -// method socket.recvfrom(bufsize) +//| .. method:: recvfrom(bufsize) +//| +//| Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| Returns a tuple containing +//| * a bytes() of length <= bufsize +//| * a remote_address, which is a tuple of ip address and port number +//| +//| :param ~int bufsize: maximum number of bytes to receive +//| + STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { @@ -275,7 +343,11 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); -// method socket.setsockopt(level, optname, value) +//| .. method:: setsockopt(level, optname, value) +//| +//| Sets socket options +//| + STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); @@ -305,10 +377,13 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt); -// method socket.settimeout(value) -// timeout=0 means non-blocking -// timeout=None means blocking -// otherwise, timeout is in seconds +//| .. method:: settimeout(value) +//| +//| Set the timeout value for this socket. +//| +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. +//| + STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->nic == MP_OBJ_NULL) { @@ -333,6 +408,13 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout); +//| .. method:: setblocking(flag) +//| +//| Set the blocking behaviour of this socket. +//| +//| :param ~bool flag: False means non-blocking, True means block indefinitely. +//| + // method socket.setblocking(flag) STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { if (mp_obj_is_true(blocking)) { @@ -386,8 +468,14 @@ STATIC const mp_obj_type_t socket_type = { .locals_dict = (mp_obj_dict_t*)&socket_locals_dict, }; -/******************************************************************************/ -// usocket module +//| .. function:: getaddrinfo(host, port) +//| +//| Gets the address information for a hostname and port +//| +//| Returns the appropriate family, socket type, socket protocol and +//| address information to call socket.socket() and socket.connect() with, +//| as a tuple. +//| STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { size_t hlen; diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c index 342cb1052..e230deecc 100644 --- a/shared-bindings/wiznet/__init__.c +++ b/shared-bindings/wiznet/__init__.c @@ -42,7 +42,7 @@ //| :synopsis: Support for WizNet hardware //| :platform: SAMD //| -//| Doc content goes here +//| Support for WizNet hardware, including the WizNet 5500 Ethernet adaptor. //| //| Libraries //| diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 32f100969..1dba5f380 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -53,6 +53,10 @@ //| .. class:: WIZNET5K(spi, cs, rst) //| //| Create a new WIZNET5500 interface using the specified pins +//| +//| :param spi: spi bus to use +//| :param cs: pin to use for Chip Select +//| :param rst: pin to sue for Reset //| STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -68,9 +72,10 @@ STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); -//| attribute:: connected +//| .. attribute:: connected //| //| is this device physically connected? +//| const mp_obj_property_t wiznet5k_connected_obj = { .base.type = &mp_type_property, @@ -79,8 +84,14 @@ const mp_obj_property_t wiznet5k_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; -/// \method ifconfig([(ip, subnet, gateway, dns)]) -/// Get/set IP address, subnet mask, gateway and DNS. +//| .. method:: ifconfig(...) +//| +//| Called without parameters, returns a tuple of +//| (ip_address, subnet_mask, gateway_address, dns_server) +//| +//| Or can be called with the same tuple to set those parameters. +//| + STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { wiz_NetInfo netinfo; ctlnetwork(CN_GET_NETINFO, &netinfo); -- cgit v1.2.3 From 88af5815ee976d26b79041575e3ae6487ab91038 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 13 Oct 2018 09:51:29 -0700 Subject: Increase clone depth (#1247) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 65983fc92..d4f21a398 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: c compiler: - gcc git: - depth: 1 + depth: 6 # Each item under 'env' is a separate Travis job to execute. # They run in separate environments, so each one must take the time -- cgit v1.2.3 From f1028b5f964117fdcca2e35c479026da4153b505 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Sat, 13 Oct 2018 10:17:13 -0700 Subject: add pin def for BAT --- ports/atmel-samd/boards/feather_m0_adalogger/pins.c | 1 + ports/atmel-samd/boards/feather_m0_basic/pins.c | 1 + ports/atmel-samd/boards/feather_m0_express/pins.c | 1 + ports/atmel-samd/boards/feather_m0_express_crickit/pins.c | 1 + ports/atmel-samd/boards/feather_m0_rfm69/pins.c | 1 + ports/atmel-samd/boards/feather_m0_rfm9x/pins.c | 1 + ports/atmel-samd/boards/feather_m0_supersized/pins.c | 1 + ports/atmel-samd/boards/feather_m4_express/pins.c | 1 + ports/atmel-samd/boards/hallowing_m0_express/pins.c | 2 +- ports/atmel-samd/boards/itsybitsy_m0_express/pins.c | 1 + ports/atmel-samd/boards/itsybitsy_m4_express/pins.c | 1 + ports/atmel-samd/boards/ugame10/pins.c | 2 +- 12 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c index da97bd253..0e010e5bf 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c +++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c @@ -28,6 +28,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c index b5bd45a2f..7cdd49e0a 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/pins.c +++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c index 1a6aad45b..d8456c83a 100644 --- a/ports/atmel-samd/boards/feather_m0_express/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c index 1a6aad45b..d8456c83a 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c index 072eb4f88..de8e3a3a5 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c index 696d2239d..049d495a3 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c index 1a6aad45b..d8456c83a 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/pins.c +++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c index b9b04e0ac..1ef0d933f 100644 --- a/ports/atmel-samd/boards/feather_m4_express/pins.c +++ b/ports/atmel-samd/boards/feather_m4_express/pins.c @@ -28,6 +28,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/hallowing_m0_express/pins.c b/ports/atmel-samd/boards/hallowing_m0_express/pins.c index d1f8609ff..4c4a62688 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/pins.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/pins.c @@ -55,7 +55,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA28) }, { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA14) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index 25407bc14..ff0515b95 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -17,6 +17,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index 2a89c3037..f6aff8717 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -37,6 +37,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c index 87ace5e96..e291e95b2 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -9,7 +9,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, { MP_ROM_QSTR(MP_QSTR_MUTE), MP_ROM_PTR(&pin_PA23) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&pin_PA03) }, { MP_ROM_QSTR(MP_QSTR_LEFT), MP_ROM_PTR(&pin_PA04) }, -- cgit v1.2.3 From 1447df3fa608d644564df72e4292541766370071 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Sun, 14 Oct 2018 23:34:49 -0700 Subject: change BAT to BATTERY --- ports/atmel-samd/boards/feather_m0_adalogger/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_basic/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_express/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_express_crickit/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_rfm69/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_rfm9x/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_supersized/pins.c | 2 +- ports/atmel-samd/boards/feather_m4_express/pins.c | 2 +- ports/atmel-samd/boards/hallowing_m0_express/pins.c | 2 +- ports/atmel-samd/boards/itsybitsy_m0_express/pins.c | 2 +- ports/atmel-samd/boards/itsybitsy_m4_express/pins.c | 2 +- ports/atmel-samd/boards/ugame10/pins.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c index 0e010e5bf..0029bba1a 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c +++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c @@ -28,7 +28,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c index 7cdd49e0a..4400a253d 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/pins.c +++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c index d8456c83a..cd6c351d4 100644 --- a/ports/atmel-samd/boards/feather_m0_express/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c index d8456c83a..cd6c351d4 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c index de8e3a3a5..7e14b3f25 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c index 049d495a3..4e77b7fb9 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c index d8456c83a..cd6c351d4 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/pins.c +++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c @@ -22,7 +22,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c index 1ef0d933f..5004254c5 100644 --- a/ports/atmel-samd/boards/feather_m4_express/pins.c +++ b/ports/atmel-samd/boards/feather_m4_express/pins.c @@ -28,7 +28,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/hallowing_m0_express/pins.c b/ports/atmel-samd/boards/hallowing_m0_express/pins.c index 4c4a62688..d1f8609ff 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/pins.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/pins.c @@ -55,7 +55,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA28) }, { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA14) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index ff0515b95..786c1a54c 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -17,7 +17,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index f6aff8717..210b2387b 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -37,7 +37,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c index e291e95b2..87ace5e96 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -9,7 +9,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, { MP_ROM_QSTR(MP_QSTR_MUTE), MP_ROM_PTR(&pin_PA23) }, - { MP_ROM_QSTR(MP_QSTR_BAT), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&pin_PA03) }, { MP_ROM_QSTR(MP_QSTR_LEFT), MP_ROM_PTR(&pin_PA04) }, -- cgit v1.2.3 From c103a05579e1d325dc66b9793681fbfa7cc397c6 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Mon, 15 Oct 2018 19:17:04 -0500 Subject: Add board Meow Meow by Electronic Cats https://github.com/ElectronicCats/MeowMeow --- ports/atmel-samd/boards/meowmeow/board.c | 38 ++++++++++++++++++++ ports/atmel-samd/boards/meowmeow/mpconfigboard.h | 36 +++++++++++++++++++ ports/atmel-samd/boards/meowmeow/mpconfigboard.mk | 11 ++++++ ports/atmel-samd/boards/meowmeow/pins.c | 43 +++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 ports/atmel-samd/boards/meowmeow/board.c create mode 100644 ports/atmel-samd/boards/meowmeow/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/meowmeow/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/meowmeow/pins.c diff --git a/ports/atmel-samd/boards/meowmeow/board.c b/ports/atmel-samd/boards/meowmeow/board.c new file mode 100644 index 000000000..881e15e0c --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Andrés Sabas for Electronic Cats + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h new file mode 100644 index 000000000..3ce00b04f --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -0,0 +1,36 @@ +#define MICROPY_HW_BOARD_NAME "Meow Meow" +#define MICROPY_HW_MCU_NAME "samd21g18" + + +// These are pins not to reset. +// PA24 and PA25 are USB. +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#include "internal_flash.h" + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define CALIBRATE_CRYSTALLESS 1 + +// Explanation of how a user got into safe mode. +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" + +#define DEFAULT_I2C_BUS_SCL (&pin_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA15) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA14) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk new file mode 100644 index 000000000..31015ad17 --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0xBAB1 +USB_PID = 0x1209 +USB_PRODUCT = "Meow Meow" +USB_MANUFACTURER = "Electronic Cats" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 \ No newline at end of file diff --git a/ports/atmel-samd/boards/meowmeow/pins.c b/ports/atmel-samd/boards/meowmeow/pins.c new file mode 100644 index 000000000..59c51f4eb --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/pins.c @@ -0,0 +1,43 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); -- cgit v1.2.3 From f6c0a23fa8d93e0341af8ec1aee9554ce5696b91 Mon Sep 17 00:00:00 2001 From: Carlos Date: Mon, 15 Oct 2018 21:41:05 -0500 Subject: Translate strings on Mixer module --- locale/es.po | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/locale/es.po b/locale/es.po index 324fe0720..60452ae34 100644 --- a/locale/es.po +++ b/locale/es.po @@ -2074,34 +2074,32 @@ msgid "" msgstr "" #: shared-bindings/audioio/Mixer.c:94 -#, fuzzy msgid "Invalid voice count" -msgstr "Dirección inválida." +msgstr "Cuenta de voces inválida" #: shared-bindings/audioio/Mixer.c:99 -#, fuzzy msgid "Invalid channel count" -msgstr "argumentos inválidos" +msgstr "Cuenta de canales inválida" #: shared-bindings/audioio/Mixer.c:103 -#, fuzzy msgid "Sample rate must be positive" -msgstr "STA debe estar activo" +msgstr "Sample rate debe ser positivo" #: shared-bindings/audioio/Mixer.c:107 -#, fuzzy msgid "bits_per_sample must be 8 or 16" -msgstr "bits debe ser 8" +msgstr "bits_per_sample debe ser 8 o 16" #: shared-bindings/audioio/RawSample.c:98 msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" +"sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' o" +"'B'" #: shared-bindings/audioio/RawSample.c:104 msgid "buffer must be a bytes-like object" -msgstr "" +msgstr "buffer debe de ser un objeto bytes-like" #: shared-bindings/audioio/WaveFile.c:78 #: shared-bindings/displayio/OnDiskBitmap.c:85 @@ -2387,31 +2385,31 @@ msgstr "" #: shared-module/audioio/Mixer.c:47 shared-module/audioio/WaveFile.c:117 msgid "Couldn't allocate first buffer" -msgstr "" +msgstr "No se pudo asignar el primer buffer" #: shared-module/audioio/Mixer.c:53 shared-module/audioio/WaveFile.c:123 msgid "Couldn't allocate second buffer" -msgstr "" +msgstr "No se pudo asignar el segundo buffer" #: shared-module/audioio/Mixer.c:82 msgid "Voice index too high" -msgstr "" +msgstr "Index de voz demasiado alto" #: shared-module/audioio/Mixer.c:85 msgid "The sample's sample rate does not match the mixer's" -msgstr "" +msgstr "El sample rate del sample no iguala al del mixer" #: shared-module/audioio/Mixer.c:88 msgid "The sample's channel count does not match the mixer's" -msgstr "" +msgstr "La cuenta de canales del sample no iguala a las del mixer" #: shared-module/audioio/Mixer.c:91 msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" +msgstr "Los bits_per_sample del sample no igualan a los del mixer" #: shared-module/audioio/Mixer.c:100 msgid "The sample's signedness does not match the mixer's" -msgstr "" +msgstr "El signo del sample no iguala al del mixer" #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" -- cgit v1.2.3 From 1f760bded8d0623c8ef5f846c3fcb4c6f13f0ce0 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 16 Oct 2018 23:07:58 +1100 Subject: header file cleanup for wiznet --- shared-module/wiznet/wiznet5k.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 5c311bf49..150478190 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -50,16 +50,7 @@ #include "internet/dns/dns.h" #include "internet/dhcp/dhcp.h" -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - busio_spi_obj_t *spi; - digitalio_digitalinout_obj_t cs; - digitalio_digitalinout_obj_t rst; - uint8_t socket_used; -} wiznet5k_obj_t; - -static wiznet5k_obj_t wiznet5k_obj; +#include "shared-module/wiznet/wiznet5k.h" STATIC wiznet5k_obj_t wiznet5k_obj; -- cgit v1.2.3 From a15f3361aa0182cbefe0aec7376ff56bdcb74aa4 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 16 Oct 2018 23:09:25 +1100 Subject: add mechanism for timer ticks in NICs --- ports/atmel-samd/background.c | 4 ++++ shared-module/network/__init__.c | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index f25ec7200..385f0c284 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -31,6 +31,7 @@ #include "usb_mass_storage.h" #include "shared-module/displayio/__init__.h" +#include "shared-module/network/__init__.h" volatile uint64_t last_finished_tick = 0; @@ -41,6 +42,9 @@ void run_background_tasks(void) { #ifdef CIRCUITPY_DISPLAYIO displayio_refresh_display(); #endif + #ifdef MICROPY_PY_NETWORK + network_module_background(); + #endif usb_msc_background(); usb_cdc_background(); last_finished_tick = ticks_ms; diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c index 6a955a0c4..a674e8478 100644 --- a/shared-module/network/__init__.c +++ b/shared-module/network/__init__.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include + #include "py/objlist.h" #include "py/runtime.h" #include "py/mphal.h" @@ -31,6 +33,8 @@ #include "shared-bindings/random/__init__.h" +#include "shared-module/network/__init__.h" + // mod_network_nic_list needs to be declared in mpconfigport.h @@ -41,6 +45,19 @@ void network_module_init(void) { void network_module_deinit(void) { } +void network_module_background(void) { + static uint32_t next_tick = 0; + uint32_t this_tick = ticks_ms; + if (this_tick < next_tick) return; + next_tick = this_tick + 1000; + + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->timer_tick != NULL) nic_type->timer_tick(nic); + } +} + void network_module_register_nic(mp_obj_t nic) { for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { -- cgit v1.2.3 From 45974978efa7e81a5a2a46bfb9f8d3cf016b1cb4 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 16 Oct 2018 23:09:55 +1100 Subject: fixup --- shared-module/network/__init__.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h index ce5b4e6d3..00a3c3957 100644 --- a/shared-module/network/__init__.h +++ b/shared-module/network/__init__.h @@ -61,6 +61,7 @@ typedef struct _mod_network_nic_type_t { int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); + void (*timer_tick)(struct _mod_network_socket_obj_t *socket); } mod_network_nic_type_t; typedef struct _mod_network_socket_obj_t { @@ -82,6 +83,7 @@ extern const mod_network_nic_type_t mod_network_nic_type_cc3k; void network_module_init(void); void network_module_deinit(void); +void network_module_background(void); void network_module_register_nic(mp_obj_t nic); mp_obj_t network_module_find_nic(const uint8_t *ip); -- cgit v1.2.3 From 06894be29415fd182e82503e3a658be5df82cebd Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Tue, 16 Oct 2018 23:10:18 +1100 Subject: timer ticks for DHCP state machine for wiznet --- shared-bindings/wiznet/wiznet5k.c | 1 + shared-module/wiznet/wiznet5k.c | 38 ++++++++++++++++++++++++-------------- shared-module/wiznet/wiznet5k.h | 2 ++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 1dba5f380..e1076bc15 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -146,6 +146,7 @@ const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { .setsockopt = wiznet5k_socket_setsockopt, .settimeout = wiznet5k_socket_settimeout, .ioctl = wiznet5k_socket_ioctl, + .timer_tick = wiznet5k_socket_timer_tick, }; #endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 150478190..4bf536226 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -317,23 +317,33 @@ int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, m } } -static void wiznet5k_try_dhcp(void) { - DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) { + if (wiznet5k_obj.dhcp_active) { + DHCP_time_handler(); + DHCP_run(); + } +} - // Set up the socket to listen on UDP 68 before calling DHCP_init - WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); - DHCP_init(0, dhcp_buf); +static void wiznet5k_start_dhcp(void) { + static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; - // try a few times for DHCP ... XXX this should be asynchronous. - for (int i=0; i<10; i++) { - DHCP_time_handler(); - int dhcp_state = DHCP_run(); - if (dhcp_state == DHCP_IP_LEASED || dhcp_state == DHCP_IP_CHANGED) break; - mp_hal_delay_ms(1000); + if (!wiznet5k_obj.dhcp_active) { + // Set up the socket to listen on UDP 68 before calling DHCP_init + WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); + DHCP_init(0, dhcp_buf); + wiznet5k_obj.dhcp_active = 1; + } +} + +#if 0 +static void wiznet5k_stop_dhcp(void) { + if (wiznet5k_obj.dhcp_active) { + wiznet5k_obj.dhcp_active = 0; + DHCP_stop(); + WIZCHIP_EXPORT(close)(0); } - DHCP_stop(); - WIZCHIP_EXPORT(close)(0); } +#endif /// Create and return a WIZNET5K object. mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { @@ -382,7 +392,7 @@ mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { // seems we need a small delay after init mp_hal_delay_ms(250); - wiznet5k_try_dhcp(); + wiznet5k_start_dhcp(); // register with network module network_module_register_nic(&wiznet5k_obj); diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h index f3e3dcfe1..04b8872fb 100644 --- a/shared-module/wiznet/wiznet5k.h +++ b/shared-module/wiznet/wiznet5k.h @@ -39,6 +39,7 @@ typedef struct _wiznet5k_obj_t { digitalio_digitalinout_obj_t cs; digitalio_digitalinout_obj_t rst; uint8_t socket_used; + bool dhcp_active; } wiznet5k_obj_t; int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip); @@ -55,6 +56,7 @@ mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket); mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); -- cgit v1.2.3 From 2262efc31155cfb498c5ecbfb64be16839cf4641 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 16 Oct 2018 11:05:02 -0400 Subject: PulseOut working --- ports/nrf/Makefile | 2 + ports/nrf/common-hal/analogio/AnalogOut.c | 9 +-- ports/nrf/common-hal/board/__init__.c | 2 +- ports/nrf/common-hal/busio/I2C.c | 1 + ports/nrf/common-hal/busio/UART.c | 4 +- ports/nrf/common-hal/pulseio/PWMOut.c | 4 +- ports/nrf/common-hal/pulseio/PulseOut.c | 123 +++++++++++++++++++++++++++--- ports/nrf/common-hal/pulseio/PulseOut.h | 6 +- ports/nrf/nrfx_config.h | 24 +++++- ports/nrf/peripherals/nrf/pins.h | 2 +- ports/nrf/peripherals/nrf/timers.c | 88 +++++++++++++++++++++ ports/nrf/peripherals/nrf/timers.h | 32 ++++++++ ports/nrf/supervisor/port.c | 19 ++--- shared-bindings/pulseio/PulseOut.c | 7 +- 14 files changed, 281 insertions(+), 42 deletions(-) create mode 100644 ports/nrf/peripherals/nrf/timers.c create mode 100644 ports/nrf/peripherals/nrf/timers.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 93ca78376..8b84f43df 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -90,6 +90,7 @@ LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc SRC_NRFX = $(addprefix nrfx/,\ drivers/src/nrfx_power.c \ drivers/src/nrfx_spim.c \ + drivers/src/nrfx_timer.c \ drivers/src/nrfx_twim.c \ drivers/src/nrfx_uarte.c \ ) @@ -123,6 +124,7 @@ SRC_C += \ peripherals/nrf/clocks.c \ peripherals/nrf/$(MCU_CHIP)/pins.c \ peripherals/nrf/$(MCU_CHIP)/power.c \ + peripherals/nrf/timers.c \ supervisor/shared/memory.c DRIVERS_SRC_C += $(addprefix modules/,\ diff --git a/ports/nrf/common-hal/analogio/AnalogOut.c b/ports/nrf/common-hal/analogio/AnalogOut.c index dc0f53740..7c60e324d 100644 --- a/ports/nrf/common-hal/analogio/AnalogOut.c +++ b/ports/nrf/common-hal/analogio/AnalogOut.c @@ -3,14 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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: + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. diff --git a/ports/nrf/common-hal/board/__init__.c b/ports/nrf/common-hal/board/__init__.c index 287f546d5..350f2eea5 100644 --- a/ports/nrf/common-hal/board/__init__.c +++ b/ports/nrf/common-hal/board/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index c2a6cab70..4c42e58cd 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -56,6 +56,7 @@ STATIC twim_peripheral_t twim_peripherals[] = { void i2c_reset(void) { for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) { + nrf_twim_disable(twim_peripherals[i].twim.p_twim); twim_peripherals[i].in_use = false; } } diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index b2dbb56a1..b9e79381a 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2018 Ha Thach for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -179,7 +179,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t self->rx_count = -1; _VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt)); } - + // queue 1-byte transfer for rx_characters_available() if ( self->rx_count == 0 ) { self->rx_count = -1; diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c index 5d94bab79..f321f848d 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.c +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -168,6 +167,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, self->frequency = frequency; self->variable_frequency = variable_frequency; + // Note this is standard, not strong drive. nrf_gpio_cfg_output(self->pin_number); // disable before mapping pin channel diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index 3495f38f7..044c4d3a8 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,31 +29,136 @@ #include #include "mpconfigport.h" +#include "nrf/pins.h" +#include "nrf/timers.h" #include "py/gc.h" #include "py/runtime.h" - #include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "supervisor/shared/translate.h" -//void pulse_finish(struct tc_module *const module) { -// -//} +// A single timer is shared amongst all PulseOut objects under the assumption that +// the code is single threaded. +static uint8_t refcount = 0; -void pulseout_reset() { +static nrfx_timer_t *timer = NULL; + +static uint16_t *pulse_array = NULL; +static volatile uint16_t pulse_array_index = 0; +static uint16_t pulse_array_length; + +static void turn_on(pulseio_pulseout_obj_t *pulseout) { + pulseout->pwmout->pwm->PSEL.OUT[0] = pulseout->pwmout->pin_number; +} + +static void turn_off(pulseio_pulseout_obj_t *pulseout) { + // Disconnect pin from PWM. + pulseout->pwmout->pwm->PSEL.OUT[0] = 0xffffffff; + // Make sure pin is low. + nrf_gpio_pin_clear(pulseout->pwmout->pin_number); +} + +static void start_timer(void) { + nrfx_timer_clear(timer); + // true enables interrupt. + nrfx_timer_compare(timer, NRF_TIMER_CC_CHANNEL0, pulse_array[pulse_array_index], true); + nrfx_timer_resume(timer); +} + +static void pulseout_event_handler(nrf_timer_event_t event_type, void *p_context) { + pulseio_pulseout_obj_t *pulseout = (pulseio_pulseout_obj_t*) p_context; + if (event_type != NRF_TIMER_EVENT_COMPARE0) { + // Spurious event. + return; + } + nrfx_timer_pause(timer); + + pulse_array_index++; + // No more pulses. Turn off output and don't restart. + if (pulse_array_index >= pulse_array_length) { + turn_off(pulseout); + return; + } + + // Alternate on and off, starting with on. + if (pulse_array_index % 2 == 0) { + turn_on(pulseout); + } else { + turn_off(pulseout); + } + + // Count up to the next given value. + start_timer(); } -void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) { - mp_raise_NotImplementedError(NULL); +void pulseout_reset() { + if (timer != NULL) { + nrf_peripherals_free_timer(timer); + } + refcount = 0; +} + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + if (refcount == 0) { + timer = nrf_peripherals_allocate_timer(); + if (timer == NULL) { + mp_raise_RuntimeError(translate("All timers in use")); + } + } + refcount++; + + nrfx_timer_config_t timer_config = { + // PulseOut durations are in microseconds, so this is convenient. + .frequency = NRF_TIMER_FREQ_1MHz, + .mode = NRF_TIMER_MODE_TIMER, + .bit_width = NRF_TIMER_BIT_WIDTH_32, + .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, + .p_context = self, + }; + + self->pwmout = carrier; + + nrfx_timer_init(timer, &timer_config, &pulseout_event_handler); + turn_off(self); } bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { - return 1; + return self->pwmout == NULL; } void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + if (common_hal_pulseio_pulseout_deinited(self)) { + return; + } + turn_on(self); + self->pwmout = NULL; + refcount--; + if (refcount == 0) { + nrf_peripherals_free_timer(timer); + } } void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { + pulse_array = pulses; + pulse_array_index = 0; + pulse_array_length = length; + + nrfx_timer_enable(timer); + + turn_on(self); + // Count up to the next given value. + start_timer(); + + while(pulse_array_index < length) { + // Do other things while we wait. The interrupts will handle sending the + // signal. + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + nrfx_timer_disable(timer); } diff --git a/ports/nrf/common-hal/pulseio/PulseOut.h b/ports/nrf/common-hal/pulseio/PulseOut.h index 9a764e302..42ec52e30 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.h +++ b/ports/nrf/common-hal/pulseio/PulseOut.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,13 +28,13 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H #include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PWMOut.h" #include "py/obj.h" typedef struct { mp_obj_base_t base; -// __IO PORT_PINCFG_Type *pincfg; - uint8_t pin; + const pulseio_pwmout_obj_t *pwmout; } pulseio_pulseout_obj_t; void pulseout_reset(void); diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index f217cb053..69b8e6a0c 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -27,8 +27,10 @@ // Enable SPIM2 and SPIM3 (if available) #define NRFX_SPIM2_ENABLED 1 -#ifdef NRF52840_XXAA +#ifdef NRF_SPIM3 #define NRFX_SPIM3_ENABLED 1 +#else + #define NRFX_SPIM3_ENABLED 0 #endif @@ -59,4 +61,24 @@ #define NRFX_PWM3_ENABLED 0 #endif +// TIMERS +#define NRFX_TIMER_ENABLED 1 +// Don't enable TIMER0: it's used by the SoftDevice. +#define NRFX_TIMER1_ENABLED 1 +#define NRFX_TIMER2_ENABLED 1 + +#ifdef NRFX_TIMER3 +#define NRFX_TIMER3_ENABLED 1 +#else +#define NRFX_TIMER3_ENABLED 0 +#endif + +#ifdef NRFX_TIMER4 +#define NRFX_TIMER4_ENABLED 1 +#else +#define NRFX_TIMER4_ENABLED 0 +#endif + +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 + #endif // NRFX_CONFIG_H__ diff --git a/ports/nrf/peripherals/nrf/pins.h b/ports/nrf/peripherals/nrf/pins.h index 01aa9e956..33462d711 100644 --- a/ports/nrf/peripherals/nrf/pins.h +++ b/ports/nrf/peripherals/nrf/pins.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2018 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c new file mode 100644 index 000000000..0027d526f --- /dev/null +++ b/ports/nrf/peripherals/nrf/timers.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseOut.h" + +#include + +#include "nrfx.h" +#include "nrfx_timer.h" + +#include "mpconfigport.h" +#include "py/runtime.h" + +STATIC nrfx_timer_t nrfx_timers[] = { +#if NRFX_CHECK(NRFX_TIMER0_ENABLED) + // Note that TIMER0 is reserved for use by the SoftDevice, so it should not usually be enabled. + NRFX_TIMER_INSTANCE(0), +#endif +#if NRFX_CHECK(NRFX_TIMER1_ENABLED) + NRFX_TIMER_INSTANCE(1), +#endif +#if NRFX_CHECK(NRFX_TIMER2_ENABLED) + NRFX_TIMER_INSTANCE(2), +#endif +#if NRFX_CHECK(NRFX_TIMER3_ENABLED) + NRFX_TIMER_INSTANCE(3), +#endif +#if NRFX_CHECK(NRFX_TIMER4_ENABLED) + NRFX_TIMER_INSTANCE(4), +#endif +}; + +static bool nrfx_timer_allocated[ARRAY_SIZE(nrfx_timers)]; + +void timers_reset(void) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + nrfx_timer_uninit(&nrfx_timers[i]); + nrfx_timer_allocated[i] = false; + } +} + +// Returns a free nrfx_timer instance, and marks it as allocated. +// The caller should init as with the desired config. +// Returns NULL if no timer is available. +nrfx_timer_t* nrf_peripherals_allocate_timer(void) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (!nrfx_timer_allocated[i]) { + nrfx_timer_allocated[i] = true; + return &nrfx_timers[i]; + } + } + return NULL; +} + +// Free a timer, which may or may not have been initialized. +void nrf_peripherals_free_timer(nrfx_timer_t* timer) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (timer == &nrfx_timers[i]) { + nrfx_timer_allocated[i] = false; + // Safe to call even if not initialized. + nrfx_timer_uninit(timer); + return; + } + } +} diff --git a/ports/nrf/peripherals/nrf/timers.h b/ports/nrf/peripherals/nrf/timers.h new file mode 100644 index 000000000..7d3815579 --- /dev/null +++ b/ports/nrf/peripherals/nrf/timers.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx.h" +#include "nrfx_timer.h" + +void timers_reset(void); +nrfx_timer_t* nrf_peripherals_allocate_timer(void); +void nrf_peripherals_free_timer(nrfx_timer_t* timer); diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index c858a3648..f98b05f5a 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -31,12 +31,14 @@ #include "nrf/cache.h" #include "nrf/clocks.h" #include "nrf/power.h" +#include "nrf/timers.h" #include "shared-module/gamepad/__init__.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/pulseio/PWMOut.h" +#include "common-hal/pulseio/PulseOut.h" #include "tick.h" safe_mode_t port_init(void) { @@ -81,6 +83,8 @@ void reset_port(void) { i2c_reset(); spi_reset(); pwmout_reset(); + pulseout_reset(); + timers_reset(); reset_all_pins(); } @@ -88,16 +92,7 @@ void reset_port(void) { void HardFault_Handler(void) { -// static volatile uint32_t reg; -// static volatile uint32_t reg2; -// static volatile uint32_t bfar; -// reg = SCB->HFSR; -// reg2 = SCB->CFSR; -// bfar = SCB->BFAR; -// for (int i = 0; i < 0; i++) -// { -// (void)reg; -// (void)reg2; -// (void)bfar; -// } + while (true) { + asm(""); + } } diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 1c97c37c3..e9834c12a 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -47,7 +47,7 @@ //| //| .. class:: PulseOut(carrier) //| -//| Create a PulseOut object associated with the given PWM out experience. +//| Create a PulseOut object associated with the given PWMout object. //| //| :param ~pulseio.PWMOut carrier: PWMOut that is set to output on the desired pin. //| @@ -57,9 +57,10 @@ //| import pulseio //| import board //| -//| pwm = pulseio.PWMOut(board.D13, duty_cycle=2 ** 15) +//| # 50% duty cycle at 38kHz. +//| pwm = pulseio.PWMOut(board.D13, frequency=38000, duty_cycle=32768) //| pulse = pulseio.PulseOut(pwm) -//| # on off on off on +//| # on off on off on //| pulses = array.array('H', [65000, 1000, 65000, 65000, 1000]) //| pulse.send(pulses) //| -- cgit v1.2.3 From b3c7746a7f48d5fa47a26a745f39b9a3e9656d2b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 16 Oct 2018 11:09:37 -0400 Subject: fix copyright notice --- ports/nrf/common-hal/analogio/AnalogOut.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/nrf/common-hal/analogio/AnalogOut.c b/ports/nrf/common-hal/analogio/AnalogOut.c index 7c60e324d..adafa15d5 100644 --- a/ports/nrf/common-hal/analogio/AnalogOut.c +++ b/ports/nrf/common-hal/analogio/AnalogOut.c @@ -5,6 +5,13 @@ * * Copyright (c) 2018 Dan Halbert for Adafruit Industries * + * 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. * -- cgit v1.2.3 From ab02a034f69eaed97f6bc4b49546ff726524a79d Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 16 Oct 2018 14:08:54 -0400 Subject: Update frozen libraries for 4.0.0-alpha.2 --- frozen/Adafruit_CircuitPython_BusDevice | 2 +- frozen/Adafruit_CircuitPython_CircuitPlayground | 2 +- frozen/Adafruit_CircuitPython_Crickit | 2 +- frozen/Adafruit_CircuitPython_DotStar | 2 +- frozen/Adafruit_CircuitPython_HID | 2 +- frozen/Adafruit_CircuitPython_IRRemote | 2 +- frozen/Adafruit_CircuitPython_LIS3DH | 2 +- frozen/Adafruit_CircuitPython_Motor | 2 +- frozen/Adafruit_CircuitPython_NeoPixel | 2 +- frozen/Adafruit_CircuitPython_Thermistor | 2 +- frozen/Adafruit_CircuitPython_seesaw | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index 079196414..97d4129b8 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit 07919641470edb602585c6a91f7b8eacf17e664b +Subproject commit 97d4129b8117d177df2675839ec4081b3570838d diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index d0aa6dc56..36ec7b371 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit d0aa6dc56d66decfae92daced7384c1e3518a666 +Subproject commit 36ec7b371f1751961de6d2c910533618d931f109 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 44f52c5da..bbf2d897a 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 44f52c5dacd9fc605565e5794e95c9a785aaf693 +Subproject commit bbf2d897ae116531bfa15af3bcb32b0123acc435 diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index af25424ee..03c24157d 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit af25424ee7dbebea3e5d77390c017018ffa52d36 +Subproject commit 03c24157d46672c723021686f7a838cfeb2db2ba diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index 5c2f6ef1e..99c71a6c1 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit 5c2f6ef1ed80f24b6a3878067d40350d3725e198 +Subproject commit 99c71a6c1ea00bc14f0a4507116ff216beafafbd diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index c29e10b59..ec11164ec 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit c29e10b590efbdf06163897b49cd0c2bea82ad6e +Subproject commit ec11164ec6682094a48d0f9848d2c4c89c08f3bc diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index c4152a0d8..377910d5a 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit c4152a0d87a04903ae0e612eb381af440c9e28b3 +Subproject commit 377910d5a9bfbf833dfd3064f80c5b2ae0c78c9a diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index e0b709f17..00326214f 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit e0b709f1710555da67705360870ba0d14ced7e06 +Subproject commit 00326214fc2ece8b31c07a654b192797e6a08043 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index e9f50cb66..4b9563d6a 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit e9f50cb6678a1684591ee021b95a3c4b51786fee +Subproject commit 4b9563d6a74c6089d0ef5466975d11ef52851bca diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 00f4ebca6..1570b23f7 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 00f4ebca6c740b76c1c464f83d514ac20b0600e1 +Subproject commit 1570b23f7a6d62e169d2fd15969e507a1da05374 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 340cd17fa..e3e3021d8 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 340cd17fad0c29d3a70d6e298a30ecc753df054e +Subproject commit e3e3021d8578fde450511b47a085d9d56ab46741 -- cgit v1.2.3 From 6a1a2c7c7bb89d1ef54d1b6faea463eb5626b557 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Tue, 16 Oct 2018 13:51:37 -0500 Subject: add auto-built by Travis --- .travis.yml | 2 +- tools/build_adafruit_bins.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 65983fc92..d51b034fb 100755 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ git: env: - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express" TRAVIS_SDK=arm diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 595d5ba5d..291a1d46e 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -27,6 +27,7 @@ itsybitsy_m0_express \ itsybitsy_m4_express \ metro_m0_express \ metro_m4_express \ +meowmeow \ pca10056 \ pca10059 \ pirkey_m0 \ -- cgit v1.2.3 From 089e2cc09901c049d30bac490a51ea49ea6d07d5 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Tue, 16 Oct 2018 14:55:21 -0700 Subject: remove BATTERY from itsybitsy --- ports/atmel-samd/boards/itsybitsy_m0_express/pins.c | 1 - ports/atmel-samd/boards/itsybitsy_m4_express/pins.c | 1 - 2 files changed, 2 deletions(-) diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index 786c1a54c..25407bc14 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -17,7 +17,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index 210b2387b..2a89c3037 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -37,7 +37,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, -- cgit v1.2.3 From c209165d4357708c5d9ed08f150206cad36e6281 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Oct 2018 13:56:02 -0700 Subject: Ramp values to and from a default value while active. This reduces the popping sound on initial playback of an audio sample. The M4 DAC has a pop on startup that cannot be prevented. It also does not allow readback so current values of the DAC are ignored. Fixes #1090 --- ports/atmel-samd/common-hal/analogio/AnalogOut.c | 12 ---- ports/atmel-samd/common-hal/audioio/AudioOut.c | 87 +++++++++++++++++++++++- ports/atmel-samd/common-hal/audioio/AudioOut.h | 1 + ports/atmel-samd/supervisor/port.c | 2 +- shared-bindings/audioio/AudioOut.c | 9 ++- shared-bindings/audioio/AudioOut.h | 2 +- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index 2e42abdd4..8419927fe 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -138,16 +138,4 @@ void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, } void analogout_reset(void) { - #if defined(SAMD21) && !defined(PIN_PA02) - return; - #endif - #ifdef SAMD21 - while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} - #endif - #ifdef SAMD51 - while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} - #endif - DAC->CTRLA.reg |= DAC_CTRLA_SWRST; - - // TODO(tannewt): Turn off the DAC clocks to save power. } diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index 0592775a5..b15c642b5 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -33,6 +33,7 @@ #include "py/runtime.h" #include "common-hal/audioio/AudioOut.h" #include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" @@ -52,11 +53,73 @@ #include "samd/pins.h" #include "samd/timers.h" +#ifdef SAMD21 +static void ramp_value(uint16_t start, uint16_t end) { + start = DAC->DATA.reg; + int32_t diff = (int32_t) end - start; + int32_t step = 49; + int32_t steps = diff / step; + if (diff < 0) { + steps *= -1; + step *= -1; + } + for (int32_t i = 0; i < steps; i++) { + uint32_t value = start + step * i; + DAC->DATA.reg = value; + DAC->DATABUF.reg = value; + common_hal_mcu_delay_us(50); + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } +} +#endif + +#ifdef SAMD51 +static void ramp_value(uint16_t start, uint16_t end) { + int32_t diff = (int32_t) end - start; + int32_t step = 49; + int32_t steps = diff / step; + if (diff < 0) { + steps *= -1; + step *= -1; + } + + for (int32_t i = 0; i < steps; i++) { + uint16_t value = start + step * i; + DAC->DATA[0].reg = value; + DAC->DATABUF[0].reg = value; + DAC->DATA[1].reg = value; + DAC->DATABUF[1].reg = value; + + common_hal_mcu_delay_us(50); + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } +} +#endif + void audioout_reset(void) { + #if defined(SAMD21) && !defined(PIN_PA02) + return; + #endif + #ifdef SAMD21 + while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} + #endif + #ifdef SAMD51 + while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} + #endif + if (DAC->CTRLA.bit.ENABLE) { + ramp_value(0x8000, 0); + } + DAC->CTRLA.reg |= DAC_CTRLA_SWRST; + + // TODO(tannewt): Turn off the DAC clocks to save power. } void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, - const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel) { + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value) { #ifdef SAMD51 bool dac_clock_enabled = hri_mclk_get_APBDMASK_DAC_bit(MCLK); #endif @@ -94,12 +157,10 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, if (right_channel != NULL) { claim_pin(right_channel); self->right_channel = right_channel; - gpio_set_pin_function(self->right_channel->number, GPIO_PIN_FUNCTION_B); audio_dma_init(&self->right_dma); } #endif self->left_channel = left_channel; - gpio_set_pin_function(self->left_channel->number, GPIO_PIN_FUNCTION_B); audio_dma_init(&self->left_dma); #ifdef SAMD51 @@ -118,6 +179,10 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, DAC->CTRLA.bit.SWRST = 1; while (DAC->CTRLA.bit.SWRST == 1) {} + // Make sure there are no outstanding access errors. (Reading DATA can cause this.) + #ifdef SAMD51 + PAC->INTFLAGD.reg = PAC_INTFLAGD_DAC; + #endif bool channel0_enabled = true; #ifdef SAMD51 @@ -159,6 +224,8 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #endif #ifdef SAMD51 while (DAC->SYNCBUSY.bit.ENABLE == 1) {} + while (channel0_enabled && DAC->STATUS.bit.READY0 == 0) {} + while (channel1_enabled && DAC->STATUS.bit.READY1 == 0) {} #endif // Use a timer to coordinate when DAC conversions occur. @@ -220,13 +287,21 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #ifdef SAMD51 connect_event_user_to_channel(EVSYS_ID_USER_DAC_START_1, channel); + if (right_channel != NULL) { + gpio_set_pin_function(self->right_channel->number, GPIO_PIN_FUNCTION_B); + } #define EVSYS_ID_USER_DAC_START EVSYS_ID_USER_DAC_START_0 #endif connect_event_user_to_channel(EVSYS_ID_USER_DAC_START, channel); + gpio_set_pin_function(self->left_channel->number, GPIO_PIN_FUNCTION_B); init_async_event_channel(channel, tc_gen_id); self->tc_to_dac_event_channel = channel; + // Ramp the DAC up. + self->default_value = default_value; + ramp_value(0, default_value); + // Leave the DMA setup to playback. } @@ -239,6 +314,9 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { return; } + // Ramp the DAC down. + ramp_value(self->default_value, 0); + DAC->CTRLA.bit.ENABLE = 0; #ifdef SAMD21 while (DAC->STATUS.bit.SYNCBUSY == 1) {} @@ -381,6 +459,9 @@ void common_hal_audioio_audioout_stop(audioio_audioout_obj_t* self) { #ifdef SAMD51 audio_dma_stop(&self->right_dma); #endif + // Ramp the DAC to default. The start is ignored when the current value can be readback. + // Otherwise, we just set it immediately. + ramp_value(self->default_value, self->default_value); } bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t* self) { diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.h b/ports/atmel-samd/common-hal/audioio/AudioOut.h index efbfe2a1d..9e5a7390d 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.h +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.h @@ -44,6 +44,7 @@ typedef struct { uint8_t tc_to_dac_event_channel; bool playing; + uint16_t default_value; } audioio_audioout_obj_t; void audioout_reset(void); diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 2349a7418..45b8ed1a4 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -249,11 +249,11 @@ void reset_port(void) { } #if defined(EXPRESS_BOARD) && !defined(__SAMR21G18A__) + audio_dma_reset(); audioout_reset(); #if !defined(__SAMD51G19A__) && !defined(__SAMD51G18A__) i2sout_reset(); #endif - audio_dma_reset(); //pdmin_reset(); #endif #ifdef SAMD21 diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index db5b371e2..8c4b92785 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -43,13 +43,15 @@ //| //| AudioOut can be used to output an analog audio signal on a given pin. //| -//| .. class:: AudioOut(left_channel, right_channel=None) +//| .. class:: AudioOut(left_channel, *, right_channel=None, default_value=0x8000) //| //| Create a AudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). //| //| :param ~microcontroller.Pin left_channel: The pin to output the left channel to //| :param ~microcontroller.Pin right_channel: The pin to output the right channel to +//| :param int default_value: The default output value. Samples should start and end with this +//| value to prevent popping. //| //| Simple 8ksps 440 Hz sin wave:: //| @@ -95,10 +97,11 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_check_num(n_args, n_kw, 1, 2, true); mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_left_channel, ARG_right_channel }; + enum { ARG_left_channel, ARG_right_channel, ARG_default_value }; static const mp_arg_t allowed_args[] = { { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_right_channel, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_default_value, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, }; 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); @@ -117,7 +120,7 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar // create AudioOut object from the given pin audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); self->base.type = &audioio_audioout_type; - common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin); + common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_default_value].u_int); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h index 751473605..d09a5c9ca 100644 --- a/shared-bindings/audioio/AudioOut.h +++ b/shared-bindings/audioio/AudioOut.h @@ -35,7 +35,7 @@ extern const mp_obj_type_t audioio_audioout_type; // left_channel will always be non-NULL but right_channel may be for mono output. void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, - const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel); + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value); void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self); bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self); -- cgit v1.2.3 From 4eb1fe18e5dfa4df03625b7d009ffbea75ea8f63 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 17 Oct 2018 11:31:08 -0700 Subject: Tweaks from feedback: * default_value is now quiescent_value * Use step = -step format for sign switch * Add note about analogout_reset being empty --- ports/atmel-samd/common-hal/analogio/AnalogOut.c | 1 + ports/atmel-samd/common-hal/audioio/AudioOut.c | 18 +++++++++--------- ports/atmel-samd/common-hal/audioio/AudioOut.h | 2 +- shared-bindings/audioio/AudioOut.c | 12 ++++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index 8419927fe..19475e00b 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -138,4 +138,5 @@ void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, } void analogout_reset(void) { + // AudioOut resets the DAC in case its been used for audio which requires special handling. } diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index b15c642b5..596f3214a 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -60,8 +60,8 @@ static void ramp_value(uint16_t start, uint16_t end) { int32_t step = 49; int32_t steps = diff / step; if (diff < 0) { - steps *= -1; - step *= -1; + steps = -steps; + step = -step; } for (int32_t i = 0; i < steps; i++) { uint32_t value = start + step * i; @@ -81,8 +81,8 @@ static void ramp_value(uint16_t start, uint16_t end) { int32_t step = 49; int32_t steps = diff / step; if (diff < 0) { - steps *= -1; - step *= -1; + steps = -steps; + step = -step; } for (int32_t i = 0; i < steps; i++) { @@ -119,7 +119,7 @@ void audioout_reset(void) { } void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, - const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value) { + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) { #ifdef SAMD51 bool dac_clock_enabled = hri_mclk_get_APBDMASK_DAC_bit(MCLK); #endif @@ -299,8 +299,8 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, self->tc_to_dac_event_channel = channel; // Ramp the DAC up. - self->default_value = default_value; - ramp_value(0, default_value); + self->quiescent_value = quiescent_value; + ramp_value(0, quiescent_value); // Leave the DMA setup to playback. } @@ -315,7 +315,7 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { } // Ramp the DAC down. - ramp_value(self->default_value, 0); + ramp_value(self->quiescent_value, 0); DAC->CTRLA.bit.ENABLE = 0; #ifdef SAMD21 @@ -461,7 +461,7 @@ void common_hal_audioio_audioout_stop(audioio_audioout_obj_t* self) { #endif // Ramp the DAC to default. The start is ignored when the current value can be readback. // Otherwise, we just set it immediately. - ramp_value(self->default_value, self->default_value); + ramp_value(self->quiescent_value, self->quiescent_value); } bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t* self) { diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.h b/ports/atmel-samd/common-hal/audioio/AudioOut.h index 9e5a7390d..56b6b75c8 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.h +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.h @@ -44,7 +44,7 @@ typedef struct { uint8_t tc_to_dac_event_channel; bool playing; - uint16_t default_value; + uint16_t quiescent_value; } audioio_audioout_obj_t; void audioout_reset(void); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 8c4b92785..18d908eef 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -43,15 +43,15 @@ //| //| AudioOut can be used to output an analog audio signal on a given pin. //| -//| .. class:: AudioOut(left_channel, *, right_channel=None, default_value=0x8000) +//| .. class:: AudioOut(left_channel, *, right_channel=None, quiescent_value=0x8000) //| //| Create a AudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). //| //| :param ~microcontroller.Pin left_channel: The pin to output the left channel to //| :param ~microcontroller.Pin right_channel: The pin to output the right channel to -//| :param int default_value: The default output value. Samples should start and end with this -//| value to prevent popping. +//| :param int quiescent_value: The output value when no signal is present. Samples should start +//| and end with this value to prevent audible popping. //| //| Simple 8ksps 440 Hz sin wave:: //| @@ -97,11 +97,11 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_check_num(n_args, n_kw, 1, 2, true); mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_left_channel, ARG_right_channel, ARG_default_value }; + enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_right_channel, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = mp_const_none} }, - { MP_QSTR_default_value, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, + { MP_QSTR_quiescent_value, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, }; 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); @@ -120,7 +120,7 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar // create AudioOut object from the given pin audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); self->base.type = &audioio_audioout_type; - common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_default_value].u_int); + common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); return MP_OBJ_FROM_PTR(self); } -- cgit v1.2.3 From 4f9c8b7361db7967fa794ea4d911ef350f23061a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 17 Oct 2018 17:45:47 -0700 Subject: Add debug info to the generated frozen_mpy.c It adds size info and uses macros for byte code to make it more readable. --- py/mkrules.mk | 2 +- tools/mpy-tool.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index e619f2bdd..aa94ba412 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -130,7 +130,7 @@ xargs -n1 "$(abspath $(MPY_CROSS))" $(MPY_CROSS_FLAGS) # to build frozen_mpy.c from all .mpy files # You need to define MPY_TOOL_LONGINT_IMPL in mpconfigport.mk # if the default will not work (mpz is the default). -$(BUILD)/frozen_mpy.c: $(BUILD)/frozen_mpy $(BUILD)/genhdr/qstrdefs.generated.h +$(BUILD)/frozen_mpy.c: $(BUILD)/frozen_mpy $(BUILD)/genhdr/qstrdefs.generated.h $(TOP)/tools/mpy-tool.py $(STEPECHO) "Creating $@" $(Q)$(MPY_TOOL) $(MPY_TOOL_LONGINT_IMPL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(shell $(FIND) -L $(BUILD)/frozen_mpy -type f -name '*.mpy') > $@ endif diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 7deb76a8d..9e103ec60 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -78,6 +78,18 @@ MP_BC_LOAD_GLOBAL = 0x1d MP_BC_LOAD_ATTR = 0x1e MP_BC_STORE_ATTR = 0x26 +# load opcode names +opcode_names = {} +with open("../../py/bc0.h") as f: + for line in f.readlines(): + if line.startswith("#define"): + s = line.split(maxsplit=3) + if len(s) < 3: + continue + _, name, value = s[:3] + opcode = int(value.strip("()"), 0) + opcode_names[opcode] = name + def make_opcode_format(): def OC4(a, b, c, d): return a | (b << 2) | (c << 4) | (d << 6) @@ -252,35 +264,48 @@ class RawCode: i += 1 RawCode.escaped_names.add(self.escaped_name) + sizes = {"bytecode": 0, "strings": 0, "raw_code_overhead": 0, "const_table_overhead": 0, "string_overhead": 0, "number_overhead": 0} # emit children first for rc in self.raw_codes: - rc.freeze(self.escaped_name + '_') + subsize = rc.freeze(self.escaped_name + '_') + for k in sizes: + sizes[k] += subsize[k] + # generate bytecode data print() print('// frozen bytecode for file %s, scope %s%s' % (self.source_file.str, parent_name, self.simple_name.str)) + print("// bytecode size", len(self.bytecode)) print('STATIC ', end='') if not config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: print('const ', end='') print('byte bytecode_data_%s[%u] = {' % (self.escaped_name, len(self.bytecode))) + sizes["bytecode"] += len(self.bytecode) print(' ', end='') for i in range(self.ip2): print(' 0x%02x,' % self.bytecode[i], end='') print() + print(" // simple name") print(' ', self.simple_name.qstr_id, '& 0xff,', self.simple_name.qstr_id, '>> 8,') + print(" // source file") print(' ', self.source_file.qstr_id, '& 0xff,', self.source_file.qstr_id, '>> 8,') print(' ', end='') for i in range(self.ip2 + 4, self.ip): - print(' 0x%02x,' % self.bytecode[i], end='') + opcode = self.bytecode[i] print() ip = self.ip while ip < len(self.bytecode): f, sz = mp_opcode_format(self.bytecode, ip) + opcode = self.bytecode[ip] + if opcode in opcode_names: + opcode = opcode_names[opcode] + else: + opcode = '0x%02x' % opcode if f == 1: qst = self._unpack_qstr(ip + 1).qstr_id - print(' ', '0x%02x,' % self.bytecode[ip], qst, '& 0xff,', qst, '>> 8,') + print(' {}, {} & 0xff, {} >> 8,'.format(opcode, qst, qst)) else: - print(' ', ''.join('0x%02x, ' % self.bytecode[ip + i] for i in range(sz))) + print(' {},{}'.format(opcode, ''.join(' 0x%02x,' % self.bytecode[ip + i] for i in range(1, sz)))) ip += sz print('};') @@ -295,9 +320,12 @@ class RawCode: obj_type = 'mp_type_str' else: obj_type = 'mp_type_bytes' - print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};' + print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"}; // %s' % (obj_name, obj_type, qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH), - len(obj), ''.join(('\\x%02x' % b) for b in obj))) + len(obj), ''.join(('\\x%02x' % b) for b in obj), obj)) + sizes["strings"] += len(obj) + sizes["string_overhead"] += 16 + elif is_int_type(obj): if config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE: # TODO check if we can actually fit this long-int into a small-int @@ -321,14 +349,17 @@ class RawCode: print('STATIC const mp_obj_int_t %s = {{&mp_type_int}, ' '{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t[]){%s}}};' % (obj_name, neg, ndigs, ndigs, bits_per_dig, digs)) + sizes["number_overhead"] += 16 elif type(obj) is float: print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B') print('STATIC const mp_obj_float_t %s = {{&mp_type_float}, %.16g};' % (obj_name, obj)) print('#endif') + sizes["number_overhead"] += 8 elif type(obj) is complex: print('STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, %.16g, %.16g};' % (obj_name, obj.real, obj.imag)) + sizes["number_overhead"] += 12 else: raise FreezeError(self, 'freezing of object %r is not implemented' % (obj,)) @@ -338,8 +369,10 @@ class RawCode: print('STATIC const mp_rom_obj_t const_table_data_%s[%u] = {' % (self.escaped_name, const_table_len)) for qst in self.qstrs: + sizes["const_table_overhead"] += 4 print(' MP_ROM_QSTR(%s),' % global_qstrs[qst].qstr_id) for i in range(len(self.objs)): + sizes["const_table_overhead"] += 4 if type(self.objs[i]) is float: print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B') print(' MP_ROM_PTR(&const_obj_%s_%u),' % (self.escaped_name, i)) @@ -353,6 +386,7 @@ class RawCode: else: print(' MP_ROM_PTR(&const_obj_%s_%u),' % (self.escaped_name, i)) for rc in self.raw_codes: + sizes["const_table_overhead"] += 4 print(' MP_ROM_PTR(&raw_code_%s),' % rc.escaped_name) print('};') @@ -376,6 +410,9 @@ class RawCode: print(' #endif') print(' },') print('};') + sizes["raw_code_overhead"] += 16 + + return sizes def read_uint(f): i = 0 @@ -467,6 +504,7 @@ def freeze_mpy(base_qstrs, raw_codes): new[q.qstr_esc] = (len(new), q.qstr_esc, q.str) new = sorted(new.values(), key=lambda x: x[0]) + print('#include "py/bc0.h"') print('#include "py/mpconfig.h"') print('#include "py/objint.h"') print('#include "py/objstr.h"') @@ -523,27 +561,45 @@ def freeze_mpy(base_qstrs, raw_codes): print(' %u, // allocated entries' % len(new)) print(' %u, // used entries' % len(new)) print(' {') + qstr_size = {"metadata": 0, "data": 0} for _, _, qstr in new: + qstr_size["metadata"] += config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH + qstr_size["data"] += len(qstr) print(' %s,' % qstrutil.make_bytes(config.MICROPY_QSTR_BYTES_IN_LEN, config.MICROPY_QSTR_BYTES_IN_HASH, qstr)) print(' },') print('};') + sizes = {} for rc in raw_codes: - rc.freeze(rc.source_file.str.replace('/', '_')[:-3] + '_') + sizes[rc.source_file.str] = rc.freeze(rc.source_file.str.replace('/', '_')[:-3] + '_') print() print('const char mp_frozen_mpy_names[] = {') + qstr_size["filenames"] = 1 for rc in raw_codes: module_name = rc.source_file.str print('"%s\\0"' % module_name) + qstr_size["filenames"] += len(module_name) + 1 print('"\\0"};') print('const mp_raw_code_t *const mp_frozen_mpy_content[] = {') for rc in raw_codes: print(' &raw_code_%s,' % rc.escaped_name) + size = sizes[rc.source_file.str] + print(' // Total size:', sum(size.values())) + for k in size: + print(" // {} {}".format(k, size[k])) print('};') + print() + print('// Total size:', sum([sum(x.values()) for x in sizes.values()]) + sum(qstr_size.values())) + for k in size: + total = sum([x[k] for x in sizes.values()]) + print("// {} {}".format(k, total)) + for k in qstr_size: + print("// qstr {} {}".format(k, qstr_size[k])) + def main(): import argparse cmd_parser = argparse.ArgumentParser(description='A tool to work with MicroPython .mpy files.') -- cgit v1.2.3 From cb0126131a08a52aa5f66ae0f705079b2ae21080 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 18 Oct 2018 10:37:42 -0700 Subject: Use python3 for mpy-tool --- py/mkenv.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mkenv.mk b/py/mkenv.mk index facb8a3c2..b76dd60f8 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -72,7 +72,7 @@ endif MAKE_FROZEN = $(PYTHON) $(TOP)/tools/make-frozen.py MPY_CROSS = $(TOP)/mpy-cross/mpy-cross -MPY_TOOL = $(PYTHON) $(TOP)/tools/mpy-tool.py +MPY_TOOL = $(PYTHON3) $(TOP)/tools/mpy-tool.py PREPROCESS_FROZEN_MODULES = PYTHONPATH=$(TOP)/tools/python-semver $(TOP)/tools/preprocess_frozen_modules.py all: -- cgit v1.2.3 From b4dcbb79b2327137a615f37556dc6ffa415658da Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 18 Oct 2018 14:23:17 -0700 Subject: Add back printing out code info. Whoops! --- tools/mpy-tool.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 9e103ec60..5ce24061b 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -289,10 +289,12 @@ class RawCode: print(' ', self.simple_name.qstr_id, '& 0xff,', self.simple_name.qstr_id, '>> 8,') print(" // source file") print(' ', self.source_file.qstr_id, '& 0xff,', self.source_file.qstr_id, '>> 8,') + print(" // code info") print(' ', end='') for i in range(self.ip2 + 4, self.ip): - opcode = self.bytecode[i] + print(' 0x%02x,' % self.bytecode[i], end='') print() + print(" // bytecode") ip = self.ip while ip < len(self.bytecode): f, sz = mp_opcode_format(self.bytecode, ip) -- cgit v1.2.3 From 3d7b96aeb1ae36deb905b7ab6091d4fc0f61482d Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Mon, 17 Sep 2018 02:45:04 -0700 Subject: Add board and pin defs for MakerDiary NRF52840 MDK --- ports/nrf/Makefile | 16 +- ports/nrf/boards/makerdiary_nrf52840_mdk/README.md | 181 +++++++++++++++++++++ ports/nrf/boards/makerdiary_nrf52840_mdk/board.c | 40 +++++ .../boards/makerdiary_nrf52840_mdk/mpconfigboard.h | 64 ++++++++ .../makerdiary_nrf52840_mdk/mpconfigboard.mk | 16 ++ ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c | 63 +++++++ 6 files changed, 372 insertions(+), 8 deletions(-) create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk/README.md create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk/board.c create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk create mode 100644 ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8b84f43df..ce9e5e664 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -300,16 +300,16 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex else ifeq ($(FLASHER), pyocd) flash: $(BUILD)/$(OUTPUT_FILENAME).hex - pyocd-flashtool -t $(MCU_SUB_VARIANT) $< --sector_erase - pyocd-tool -t $(MCU_SUB_VARIANT) erase $(BOOT_SETTING_ADDR) - pyocd-tool -t $(MCU_SUB_VARIANT) write32 $(BOOT_SETTING_ADDR) 0x00000001 - pyocd-tool -t $(MCU_SUB_VARIANT) reset + pyocd-flashtool -t nrf52 $< # --sector_erase + #pyocd-tool -t nrf52 erase $(BOOT_SETTING_ADDR) + #pyocd-tool -t nrf52 write32 $(BOOT_SETTING_ADDR) 0x00000001 + #pyocd-tool -t nrf52 reset sd: $(BUILD)/$(OUTPUT_FILENAME).hex - pyocd-flashtool -t $(MCU_SUB_VARIANT) --chip_erase - pyocd-flashtool -t $(MCU_SUB_VARIANT) $(SOFTDEV_HEX) - pyocd-flashtool -t $(MCU_SUB_VARIANT) $< --sector_erase - pyocd-tool -t $(MCU_SUB_VARIANT) reset $(BOOT_SETTING_ADDR) + pyocd-flashtool -t nrf52 --chip_erase + pyocd-flashtool -t nrf52 $(SOFTDEV_HEX) + pyocd-flashtool -t nrf52 $< --sector_erase + pyocd-tool -t nrf52 reset $(BOOT_SETTING_ADDR) endif diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md new file mode 100644 index 000000000..dfa794349 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md @@ -0,0 +1,181 @@ +# Setup + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +You then need to download the SD and Nordic SDK files via: + +> This script relies on `wget`, which must be available from the command line. + +``` +$ cd ports/nrf +$ ./drivers/bluetooth/download_ble_stack.sh +``` + +## Note about bootloaders + +While most Adafruit devices come with (or can easily be flashed with) an +Adafruit-provided bootloader (supporting niceties like UF2 flashing) + +### Install `nrfjprog` + +Before you can install the bootloader, you will first need to install the +`nrfjprog` tool from Nordic Semiconductors for your operating system. The +binary files can be downloaded via the following links: + +- [nRF5x toolset tar for Linux 32-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux32/52619) +- [nRF5x toolset tar for Linux 64-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux64/51388) +- [nRF5x toolset tar for OSX v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-OSX/53406) +- [nRF5x toolset installer for Windows v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Win32/48768) + +You will then need to add the `nrfjprog` folder to your system `PATH` variable +so that it is available from the command line. The exact process for this is +OS specific, but on a POSIX type system like OS X or Linux, you can +temporarily add the location to your `PATH` environment variables as follows: + +``` +$ export PATH=$PATH:YOURPATHHERE/nRF5x-Command-Line-Tools_9_7_2_OSX/nrfjprog/ +``` + +You can test this by running the following command: + +``` +$ nrfjprog --version +nrfjprog version: 9.7.2 +JLinkARM.dll version: 6.20f +``` + +### Flash the USB CDC Bootloader with 'nrfjprog' + +> This operation only needs to be done once, and only on boards that don't + already have the serial bootloader installed. + +Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory + +``` +$ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git +$ cd Adafruit_nRF52_Bootloader +``` + +Once `nrfjprog` is installed and available in `PATH` you can flash your +board with the serial bootloader via the following command: + +``` +make BOARD=feather_nrf52840_express VERSION=latest flash +``` + +This should give you the following (or very similar) output, and you will see +a DFU blinky pattern on one of the board LEDs: + +``` +$ make BOARD=pca10056 VERSION=latest flash +Flashing: bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex +nrfjprog --program bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex --chiperase -f nrf52 --reset +Parsing hex file. +Erasing user available code and UICR flash areas. +Applying system reset. +Checking that the area to write is not protected. +Programing device. +Applying system reset. +Run. +``` + +From this point onward, you can now use a simple serial port for firmware +updates. + +Note: You can specify other version that are available in the directory `Adafruit_nRF52_Bootloader/bin/feather_nrf52840_express/` . The `VERSION=latest` will use the latest bootloader available. + +### IMPORTANT: Disable Mass Storage on PCA10056 J-Link + +The J-Link firmware on the PCA10056 implement USB Mass Storage, but this +causes a known conflict with reliable USB CDC serial port communication. In +order to use the serial bootloader, **you must disable MSD support on the +Segger J-Link**! + +To disable mass storage support, run the `JLinkExe` (or equivalent) command, +and send `MSDDisable`. (You can re-enable MSD support via `MSDEnable`): + +``` +$ JLinkExe +SEGGER J-Link Commander V6.20f (Compiled Oct 13 2017 17:20:01) +DLL version V6.20f, compiled Oct 13 2017 17:19:52 + +Connecting to J-Link via USB...O.K. +Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jul 24 2017 17:30:12 +Hardware version: V1.00 +S/N: 683947110 +VTref = 3.300V + + +Type "connect" to establish a target connection, '?' for help +J-Link>MSDDisable +Probe configured successfully. +J-Link>exit +``` + +## Building and Flashing CircuitPython + +### Installing `adafruit-nrfutil` + +run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi + +``` +$ pip3 install adafruit-nrfutil --user +``` + +### Flashing CircuitPython with USB CDC + +With the serial bootloader present on your board, you first need to force your +board into DFU mode by holding down BUTTON1 and RESETTING the board (with +BUTTON1 still pressed as you come out of reset). + +This will give you a **fast blinky DFU pattern** to indicate you are in DFU +mode. + +You can **build and flash** a CircuitPython binary via the following command: + +``` +$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all dfu-gen dfu-flash +``` + +This should give you the following results: + +``` +$make V=1 BOARD=feather52840 SD=s140 SERIAL=/dev/tty.usbmodem1411 dfu-gen dfu-flash +nrfutil dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application build-feather52840-s140/firmware.hex build-feather52840-s140/dfu-package.zip +Zip created at build-feather52840-s140/dfu-package.zip +nrfutil --verbose dfu serial --package build-feather52840-s140/dfu-package.zip -p /dev/ttyACM1 -b 115200 --singlebank +Upgrading target on /dev/ttyACM1 with DFU package /home/hathach/Dropbox/adafruit/circuitpython/ada_cp/ports/nrf/build-feather52840-s140/dfu-package.zip. Flow control is disabled, Single bank mode +Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 199840 +Sending DFU start packet +Sending DFU init packet +Sending firmware file +######################################################################################################################################################################################################################################################################################################################################################################################################### +Activating new firmware + +DFU upgrade took 8.50606513023s +Device programmed. +``` + +### Flashing CircuitPython with MSC UF2 + +uf2 file is generated last by `all` target + +``` +$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all +Create firmware.uf2 +../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-feather52840-s140/firmware.uf2" "build-feather52840-s140/firmware.hex" +Converting to uf2, output size: 392192, start address: 0x26000 +Wrote 392192 bytes to build-feather52840-s140/firmware.uf2. +``` + +Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c new file mode 100644 index 000000000..a6d050fce --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "usb.h" + +void board_init(void) { + usb_init(); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h new file mode 100644 index 000000000..0a0321fcf --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#define FEATHER52840 + +#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDK" + +#define MICROPY_QSPI_DATA0 (&pin_P1_05) +#define MICROPY_QSPI_DATA1 (&pin_P1_04) +#define MICROPY_QSPI_DATA2 (&pin_P1_02) +#define MICROPY_QSPI_DATA3 (&pin_P1_01) +#define MICROPY_QSPI_SCK (&pin_P1_03) +#define MICROPY_QSPI_CS (&pin_P1_06) + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define PORT_HEAP_SIZE (128 * 1024) +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +// TODO #include "external_flash/devices.h" + +#define EXTERNAL_FLASH_DEVICE_COUNT 1 +// Datasheet for when this is implemented: +// http://www.mxic.com.tw/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf +#define EXTERNAL_FLASH_DEVICES MX25R6435F + +#define EXTERNAL_FLASH_QSPI_DUAL + +// TODO include "external_flash/external_flash.h" + +#define BOARD_HAS_CRYSTAL 0 + +#define DEFAULT_UART_BUS_RX (&pin_P0_19) +#define DEFAULT_UART_BUS_TX (&pin_P0_20) diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk new file mode 100644 index 000000000..caf580ec4 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk @@ -0,0 +1,16 @@ +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c new file mode 100644 index 000000000..27f0c6797 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_AIN4), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_AIN6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_AIN7), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P31), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_CSN), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_P1_01) }, + + { MP_ROM_QSTR(MP_QSTR_TXD), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_RXD), MP_ROM_PTR(&pin_P0_19) }, + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_USR_BTN), MP_ROM_PTR(&pin_P1_00) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); -- cgit v1.2.3 From 16ca9c8c7c7cb17eb9aa0a9728052d7ef957713b Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 20 Oct 2018 02:39:09 -0700 Subject: Makefile fixes and some docs --- ports/nrf/Makefile | 16 +- ports/nrf/README.md | 2 + ports/nrf/boards/makerdiary_nrf52840_mdk/README.md | 213 +++++++-------------- 3 files changed, 76 insertions(+), 155 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index ce9e5e664..a1a6a4d35 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -300,16 +300,16 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex else ifeq ($(FLASHER), pyocd) flash: $(BUILD)/$(OUTPUT_FILENAME).hex - pyocd-flashtool -t nrf52 $< # --sector_erase - #pyocd-tool -t nrf52 erase $(BOOT_SETTING_ADDR) - #pyocd-tool -t nrf52 write32 $(BOOT_SETTING_ADDR) 0x00000001 - #pyocd-tool -t nrf52 reset + pyocd-flashtool -t $(MCU_VARIANT) $< --sector_erase + #pyocd-tool -t $(MCU_VARIANT) erase $(BOOT_SETTING_ADDR) + pyocd-tool -t $(MCU_VARIANT) write32 $(BOOT_SETTING_ADDR) 0x00000001 + pyocd-tool -t $(MCU_VARIANT) reset sd: $(BUILD)/$(OUTPUT_FILENAME).hex - pyocd-flashtool -t nrf52 --chip_erase - pyocd-flashtool -t nrf52 $(SOFTDEV_HEX) - pyocd-flashtool -t nrf52 $< --sector_erase - pyocd-tool -t nrf52 reset $(BOOT_SETTING_ADDR) + pyocd-flashtool -t $(MCU_VARIANT) --chip_erase + pyocd-flashtool -t $(MCU_VARIANT) $(SOFTDEV_HEX) + pyocd-flashtool -t $(MCU_VARIANT) $< --sector_erase + pyocd-tool -t $(MCU_VARIANT) reset $(BOOT_SETTING_ADDR) endif diff --git a/ports/nrf/README.md b/ports/nrf/README.md index c21bd5d63..4bd865400 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -39,6 +39,7 @@ the following links: * Adafruit [Feather nRF52](boards/feather_nrf52832/README.md): 512KB Flash, 64KB SRAM * Adafruit [Feather nRF52840](boards/feather_nrf52840_express/README.md): 1MB Flash, 256KB SRAM * Nordic PCA10056 see [Feather nRF52840](boards/pca10056/README.md) +* MakerDiary NRF52840 MDK see [its README](boards/makerdiary_nrf52840_mdk/README.md) For all other board targets, see the generic notes below. @@ -80,6 +81,7 @@ pca10040 | s132 | Peripheral and Scanner | [S pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets) feather_nrf52832 | s132 | Peripheral and Scanner | [UART DFU](#dfu-targets) feather_nrf52840_express | s140 | Peripheral and Scanner | UF2 bootloader +makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink ## Segger Targets diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md index dfa794349..826b93051 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md @@ -1,4 +1,20 @@ -# Setup +# MakerDiary NRF52840 MDK + +Refer to https://github.com/makerdiary/nrf52840-mdk or +https://wiki.makerdiary.com/nrf52840-mdk/ for more details about the device. + +Notably, CircuitPython does not currently support QSPI external flash on NRF +devices, so neither does this port. Don't store anything you care to read in +Python on that giant 64MB flash device for now - the 64MB drive that shows up on +your computer is actually part of the MSC driver provided by the DAPLink +debugger. You'll still have access to 256KB of the onboard flash, however, for +storing your Python files, cat pictures, or whatever. + +It's also interesting to note that all three LEDs and the "user button" on this +device are wired through sinks, not sources, so flip your boolean expectations +when dealing with `digitalio.DigitalInOut` on this device - `my_led.value = +True` turns the LED off! Likewise, the user button will read `False` when +pressed. ## Installing CircuitPython submodules @@ -24,158 +40,61 @@ $ ./drivers/bluetooth/download_ble_stack.sh ## Note about bootloaders While most Adafruit devices come with (or can easily be flashed with) an -Adafruit-provided bootloader (supporting niceties like UF2 flashing) - -### Install `nrfjprog` - -Before you can install the bootloader, you will first need to install the -`nrfjprog` tool from Nordic Semiconductors for your operating system. The -binary files can be downloaded via the following links: - -- [nRF5x toolset tar for Linux 32-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux32/52619) -- [nRF5x toolset tar for Linux 64-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux64/51388) -- [nRF5x toolset tar for OSX v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-OSX/53406) -- [nRF5x toolset installer for Windows v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Win32/48768) - -You will then need to add the `nrfjprog` folder to your system `PATH` variable -so that it is available from the command line. The exact process for this is -OS specific, but on a POSIX type system like OS X or Linux, you can -temporarily add the location to your `PATH` environment variables as follows: - -``` -$ export PATH=$PATH:YOURPATHHERE/nRF5x-Command-Line-Tools_9_7_2_OSX/nrfjprog/ -``` - -You can test this by running the following command: - -``` -$ nrfjprog --version -nrfjprog version: 9.7.2 -JLinkARM.dll version: 6.20f -``` - -### Flash the USB CDC Bootloader with 'nrfjprog' +Adafruit-provided bootloader (supporting niceties like UF2 flashing), this +board comes with DAPLink which (apparently?) handles everything from debugging +to programming the device, as well as the boot sequence. What's particularly +awesome about this board is that there is no physical interaction with the board +required to flash new code (read: CircuitPython builds) - the device is _always_ +listening for new firmware uploads (via `pyocd-flashtool`), even if userspace +code is running. -> This operation only needs to be done once, and only on boards that don't - already have the serial bootloader installed. - -Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory - -``` -$ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git -$ cd Adafruit_nRF52_Bootloader -``` +## Building and Flashing CircuitPython -Once `nrfjprog` is installed and available in `PATH` you can flash your -board with the serial bootloader via the following command: +You'll need to have [pyocd](https://github.com/mbedmicro/pyOCD) installed as +appropriate for your system. -``` -make BOARD=feather_nrf52840_express VERSION=latest flash +```sh +make BOARD=makerdiary_nrf52840_mdk FLASHER=pyocd SD=s140 flash ``` This should give you the following (or very similar) output, and you will see a DFU blinky pattern on one of the board LEDs: ``` -$ make BOARD=pca10056 VERSION=latest flash -Flashing: bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex -nrfjprog --program bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex --chiperase -f nrf52 --reset -Parsing hex file. -Erasing user available code and UICR flash areas. -Applying system reset. -Checking that the area to write is not protected. -Programing device. -Applying system reset. -Run. -``` - -From this point onward, you can now use a simple serial port for firmware -updates. - -Note: You can specify other version that are available in the directory `Adafruit_nRF52_Bootloader/bin/feather_nrf52840_express/` . The `VERSION=latest` will use the latest bootloader available. - -### IMPORTANT: Disable Mass Storage on PCA10056 J-Link - -The J-Link firmware on the PCA10056 implement USB Mass Storage, but this -causes a known conflict with reliable USB CDC serial port communication. In -order to use the serial bootloader, **you must disable MSD support on the -Segger J-Link**! - -To disable mass storage support, run the `JLinkExe` (or equivalent) command, -and send `MSDDisable`. (You can re-enable MSD support via `MSDEnable`): - -``` -$ JLinkExe -SEGGER J-Link Commander V6.20f (Compiled Oct 13 2017 17:20:01) -DLL version V6.20f, compiled Oct 13 2017 17:19:52 - -Connecting to J-Link via USB...O.K. -Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jul 24 2017 17:30:12 -Hardware version: V1.00 -S/N: 683947110 -VTref = 3.300V - - -Type "connect" to establish a target connection, '?' for help -J-Link>MSDDisable -Probe configured successfully. -J-Link>exit -``` - -## Building and Flashing CircuitPython - -### Installing `adafruit-nrfutil` - -run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi - -``` -$ pip3 install adafruit-nrfutil --user -``` - -### Flashing CircuitPython with USB CDC - -With the serial bootloader present on your board, you first need to force your -board into DFU mode by holding down BUTTON1 and RESETTING the board (with -BUTTON1 still pressed as you come out of reset). - -This will give you a **fast blinky DFU pattern** to indicate you are in DFU -mode. - -You can **build and flash** a CircuitPython binary via the following command: - -``` -$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all dfu-gen dfu-flash -``` - -This should give you the following results: - -``` -$make V=1 BOARD=feather52840 SD=s140 SERIAL=/dev/tty.usbmodem1411 dfu-gen dfu-flash -nrfutil dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application build-feather52840-s140/firmware.hex build-feather52840-s140/dfu-package.zip -Zip created at build-feather52840-s140/dfu-package.zip -nrfutil --verbose dfu serial --package build-feather52840-s140/dfu-package.zip -p /dev/ttyACM1 -b 115200 --singlebank -Upgrading target on /dev/ttyACM1 with DFU package /home/hathach/Dropbox/adafruit/circuitpython/ada_cp/ports/nrf/build-feather52840-s140/dfu-package.zip. Flow control is disabled, Single bank mode -Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 199840 -Sending DFU start packet -Sending DFU init packet -Sending firmware file -######################################################################################################################################################################################################################################################################################################################################################################################################### -Activating new firmware - -DFU upgrade took 8.50606513023s -Device programmed. -``` - -### Flashing CircuitPython with MSC UF2 - -uf2 file is generated last by `all` target - -``` -$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all -Create firmware.uf2 -../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-feather52840-s140/firmware.uf2" "build-feather52840-s140/firmware.hex" -Converting to uf2, output size: 392192, start address: 0x26000 -Wrote 392192 bytes to build-feather52840-s140/firmware.uf2. -``` - -Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. +$ make BOARD=makerdiary_nrf52840_mdk FLASHER=pyocd SD=s140 flash +Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity. +pyocd-flashtool -t nrf52 build-makerdiary_nrf52840_mdk-s140/firmware.hex --sector_erase +INFO:root:DAP SWD MODE initialised +INFO:root:ROM table #0 @ 0xe00ff000 cidr=b105100d pidr=2002c4008 +INFO:root:[0] +WARNING:root:Invalid coresight component, cidr=0x0 +INFO:root:[1] +INFO:root:[2] +WARNING:root:Invalid coresight component, cidr=0x1010101 +INFO:root:[3] +WARNING:root:Invalid coresight component, cidr=0x0 +INFO:root:[4] +INFO:root:[5] +INFO:root:CPU core is Cortex-M4 +INFO:root:FPU present +INFO:root:6 hardware breakpoints, 4 literal comparators +INFO:root:4 hardware watchpoints +[====================] 100% +INFO:root:Programmed 237568 bytes (58 pages) at 14.28 kB/s +#pyocd-tool -t nrf52 erase 0xFF000 +pyocd-tool -t nrf52 write32 0xFF000 0x00000001 +WARNING:root:Invalid coresight component, cidr=0x0 +WARNING:root:Invalid coresight component, cidr=0x1010101 +WARNING:root:Invalid coresight component, cidr=0x0 +pyocd-tool -t nrf52 reset +WARNING:root:Invalid coresight component, cidr=0x0 +WARNING:root:Invalid coresight component, cidr=0x1010101 +WARNING:root:Invalid coresight component, cidr=0x0 +Resetting target +``` + +Alternatively (and untested by me), it's apparently possible to copy +`firmware.hex` to the MSC device provided by DAPLink and flash that way. Refer +to [the upstream +documentation](https://wiki.makerdiary.com/nrf52840-mdk/getting-started/#drag-n-drop-programming) +for details. -- cgit v1.2.3 From 99edeed2e7b11e105a7a4479537521daf201b745 Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 20 Oct 2018 02:42:18 -0700 Subject: Build this thing! --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d4f21a398..c56664d16 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 + - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express makerdiary_nrf52840_mdk" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm -- cgit v1.2.3 From 4c75a60bd3a8f56b5ebb935ea5f5dbec5cb3fc7a Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 20 Oct 2018 02:57:17 -0700 Subject: Declobber a DEFINE --- ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h index 0a0321fcf..b33fb2dd6 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h @@ -25,7 +25,7 @@ * THE SOFTWARE. */ -#define FEATHER52840 +#define MAKERDIARYNRF52840MDK #define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK" #define MICROPY_HW_MCU_NAME "nRF52840" -- cgit v1.2.3 From aefabc5353cf8507b15f77a17ab38023324f3040 Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 20 Oct 2018 03:29:20 -0700 Subject: Update docs to reflect proper size of device --- ports/nrf/boards/makerdiary_nrf52840_mdk/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md index 826b93051..f1ba8151a 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md @@ -4,10 +4,12 @@ Refer to https://github.com/makerdiary/nrf52840-mdk or https://wiki.makerdiary.com/nrf52840-mdk/ for more details about the device. Notably, CircuitPython does not currently support QSPI external flash on NRF -devices, so neither does this port. Don't store anything you care to read in -Python on that giant 64MB flash device for now - the 64MB drive that shows up on -your computer is actually part of the MSC driver provided by the DAPLink -debugger. You'll still have access to 256KB of the onboard flash, however, for +devices, so neither does this port - the 64Mb flash device is not used for +anything. Also, don't confuse this with the 64MiB drive that shows up on your +computer - it's actually part of the MSC driver provided by the DAPLink +debugger, and is inaccessible at all from Python land (this drive is where you +can copy `firmware.hex` if you'd prefer to flash that way as opposed to with +`pyocd`. You'll still have access to 256KB of the onboard flash, however, for storing your Python files, cat pictures, or whatever. It's also interesting to note that all three LEDs and the "user button" on this -- cgit v1.2.3 From 4a409192286cddf7de33d3aa2b594db5e35bafef Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 20 Oct 2018 03:36:55 -0700 Subject: Make sure port is built as an NRF hex correctly --- tools/build_adafruit_bins.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 595d5ba5d..07581edbe 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -25,6 +25,7 @@ grandcentral_m4_express \ hallowing_m0_express \ itsybitsy_m0_express \ itsybitsy_m4_express \ +makerdiary_nrf52840_mdk \ metro_m0_express \ metro_m4_express \ pca10056 \ @@ -81,6 +82,11 @@ for board in $boards; do (( exit_status = exit_status || $? )) temp_filename=ports/nrf/build-$board-s140/firmware.uf2 extension=uf2 + elif [[ $board == "makerdiary_nrf52840_mdk" ]]; then + make $PARALLEL -C ports/nrf TRANSLATION=$language BOARD=$board SD=s140 + (( exit_status = exit_status || $? )) + temp_filename=ports/nrf/build-$board-s140/firmware.hex + extension=hex else time make $PARALLEL -C ports/atmel-samd TRANSLATION=$language BOARD=$board (( exit_status = exit_status || $? )) -- cgit v1.2.3 From aeb538521747552229c0b777e3a145592cdc6f5f Mon Sep 17 00:00:00 2001 From: Carlos Date: Sat, 20 Oct 2018 19:46:17 -0500 Subject: [locale\es] Keep already translated strings up to date --- locale/es.po | 200 +++++++++++++++++++++++++---------------------------------- 1 file changed, 84 insertions(+), 116 deletions(-) diff --git a/locale/es.po b/locale/es.po index 60452ae34..59b8d6353 100644 --- a/locale/es.po +++ b/locale/es.po @@ -65,7 +65,7 @@ msgstr "string de longitud impar" #: extmod/modubinascii.c:101 msgid "non-hex digit found" -msgstr "se encontró un digito no hexadecimal" +msgstr "se encontró un digito non-hex" #: extmod/modubinascii.c:169 msgid "incorrect padding" @@ -81,7 +81,7 @@ msgstr "No se puede obtener inequívocamente sizeof escalar" #: extmod/moductypes.c:397 msgid "struct: no fields" -msgstr "struct: no fields" +msgstr "struct: sin campos" #: extmod/moductypes.c:530 msgid "struct: cannot index" @@ -121,7 +121,7 @@ msgstr "certificado inválido" #: extmod/modutimeq.c:131 msgid "queue overflow" -msgstr "desborde de queue" +msgstr "desbordamiento de queue" #: extmod/moduzlib.c:98 msgid "compression header" @@ -132,16 +132,14 @@ msgid "invalid dupterm index" msgstr "index dupterm inválido" #: extmod/vfs_fat.c:426 py/moduerrno.c:150 -#, fuzzy msgid "Read-only filesystem" -msgstr "sistema de archivos de Solo-Lectura" +msgstr "Sistema de archivos de solo-Lectura" #: extmod/vfs_posix_file.c:48 ports/unix/file.c:50 py/objstringio.c:43 msgid "I/O operation on closed file" msgstr "Operación I/O en archivo cerrado" #: lib/embed/abort_.c:8 -#, fuzzy msgid "abort() called" msgstr "se llamó abort()" @@ -158,21 +156,20 @@ msgid " output:\n" msgstr " salida:\n" #: main.c:157 main.c:230 -#, fuzzy msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" "Auto-reload habilitado. Simplemente guarda los archivos via USB para " -"ejecutarlos o entra REPL para desabilitarlos.\n" +"ejecutarlos o entra al REPL para desabilitarlos.\n" #: main.c:159 msgid "Running in safe mode! Auto-reload is off.\n" -msgstr "Ejecutando en modo seguro! Auto-recarga esta deshabilitado.\n" +msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n" #: main.c:161 main.c:232 msgid "Auto-reload is off.\n" -msgstr "Auto-reload deshabilitado.\n" +msgstr "Auto-recarga deshabilitado.\n" #: main.c:175 msgid "Running in safe mode! Not running saved code.\n" @@ -184,7 +181,7 @@ msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" #: main.c:239 msgid "You requested starting safe mode by " -msgstr "Solicitaste iniciar en modo seguro con " +msgstr "Solicitaste iniciar en modo seguro por " #: main.c:242 msgid "To exit, please reset the board without " @@ -200,28 +197,27 @@ msgstr "" #: main.c:251 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -"Parece que nuestro código del núcleo CircuitPython dejó de funcionar. " -"Whoops!\n" +"Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" #: main.c:252 #, fuzzy msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -"Por favor registra un problema aquí con los contenidos de tu unidad de " +"Por favor registra un issue en el siguiente URL con los contenidos de tu unidad de " "almacenamiento CIRCUITPY:\n" #: main.c:255 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" -msgstr "" +msgstr "La alimentación del microcontrolador cayó. Por favor asegurate de que tu fuente de alimentación provee" #: main.c:256 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -"suficiente poder para todo el circuito y pulsa reset (después de expulsar " +"suficiente poder para todo el circuito y presiona reset (después de expulsar " "CIRCUITPY).\n" #: main.c:260 @@ -261,7 +257,7 @@ msgstr "Sin bus UART por default" #: ports/atmel-samd/common-hal/analogio/AnalogIn.c:63 #: ports/nrf/common-hal/analogio/AnalogIn.c:39 msgid "Pin does not have ADC capabilities" -msgstr "pin no tiene capacidades ADC" +msgstr "Pin no tiene capacidad ADC" #: ports/atmel-samd/common-hal/analogio/AnalogOut.c:49 msgid "No DAC on chip" @@ -278,7 +274,7 @@ msgstr "Pin bit clock inválido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 msgid "Bit clock and word select must share a clock unit" -msgstr "Bit clock y Word select deben compartir la unidad de reloj" +msgstr "Bit clock y word select deben compartir una unidad de reloj" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:156 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:130 @@ -299,11 +295,11 @@ msgstr "Clock unit está siendo utilizado" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:240 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:172 msgid "Unable to find free GCLK" -msgstr "No se pudo encontrar un GCLK disponible" +msgstr "No se pudo encontrar un GCLK libre" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:254 msgid "Too many channels in sample." -msgstr "Demasiados canales en sample" +msgstr "Demasiados canales en sample." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 #: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 @@ -321,11 +317,11 @@ msgstr "Pin clock inválido" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:134 msgid "Only 8 or 16 bit mono with " -msgstr "Solo mono de 8 o 16 bit con" +msgstr "Solo mono de 8 o 16 bit con " #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:167 msgid "sampling rate out of range" -msgstr "velocidad de muestreo fuera de rango" +msgstr "frecuencia de muestreo fuera de rango" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 msgid "DAC already in use" @@ -333,13 +329,13 @@ msgstr "DAC ya está siendo utilizado" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 msgid "Right channel unsupported" -msgstr "El canal derecho no tiene soporte" +msgstr "Canal derecho no soportado" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" -msgstr "pin inválido" +msgstr "Pin inválido" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 msgid "Invalid pin for left channel" @@ -351,22 +347,22 @@ msgstr "Pin inválido para canal derecho" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 msgid "Cannot output both channels on the same pin" -msgstr "No es posible utilizar el mismo pin para ambos canales" +msgstr "No se puede tener ambos canales en el mismo pin" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 msgid "All timers in use" -msgstr "Todos los timers están siendo utilizados" +msgstr "Todos los timers en uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 msgid "All event channels in use" -msgstr "Todos los canales de eventos están siendo utilizados" +msgstr "Todos los event channels en uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 #, c-format msgid "Sample rate too high. It must be less than %d" -msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor que %d" +msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor a %d" #: ports/atmel-samd/common-hal/busio/I2C.c:71 msgid "Not enough pins available" @@ -386,21 +382,21 @@ msgstr "SDA o SCL necesitan una pull up" #: ports/atmel-samd/common-hal/busio/I2C.c:121 msgid "Unsupported baudrate" -msgstr "Baudrate sin soporte" +msgstr "Baudrate no soportado" #: ports/atmel-samd/common-hal/busio/UART.c:66 msgid "bytes > 8 bits not supported" -msgstr "bytes > 8 bits no son soportados" +msgstr "bytes > 8 bits no soportados" #: ports/atmel-samd/common-hal/busio/UART.c:72 #: ports/nrf/common-hal/busio/UART.c:82 msgid "tx and rx cannot both be None" -msgstr "tx y rx no pueden ser ambos None" +msgstr "Ambos tx y rx no pueden ser None" #: ports/atmel-samd/common-hal/busio/UART.c:145 #: ports/nrf/common-hal/busio/UART.c:115 msgid "Failed to allocate RX buffer" -msgstr "Fallo la asignación del buffer RX" +msgstr "Ha fallado la asignación del buffer RX" #: ports/atmel-samd/common-hal/busio/UART.c:153 msgid "Could not initialize UART" @@ -419,12 +415,12 @@ msgstr "Sin pin TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 #: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 msgid "Cannot get pull while in output mode" -msgstr "No se puede obtener pull mientras en modo de salida" +msgstr "No puede ser pull mientras este en modo de salida" #: ports/atmel-samd/common-hal/microcontroller/__init__.c:74 #: ports/esp8266/common-hal/microcontroller/__init__.c:64 msgid "Cannot reset into bootloader because no bootloader is present." -msgstr "No se puede reiniciar en bootloader porque no hay bootloader presente." +msgstr "No se puede reiniciar a bootloader porque no hay bootloader presente." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 @@ -439,7 +435,7 @@ msgstr "Todos los timers para este pin están siendo utilizados" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:110 msgid "No hardware support on pin" -msgstr "pin no tiene soporte en hardware" +msgstr "Sin soporte de hardware en pin" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:113 msgid "EXTINT channel already in use" @@ -449,12 +445,12 @@ msgstr "El canal EXTINT ya está siendo utilizado" #: ports/esp8266/common-hal/pulseio/PulseIn.c:86 #, c-format msgid "Failed to allocate RX buffer of %d bytes" -msgstr "Fallo la asignación del buffer RX de %d bytes" +msgstr "Falló la asignación del buffer RX de %d bytes" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:205 #: ports/esp8266/common-hal/pulseio/PulseIn.c:151 msgid "pop from an empty PulseIn" -msgstr "pop en un PulseIn vacío" +msgstr "pop de un PulseIn vacío" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c:237 #: ports/esp8266/common-hal/pulseio/PulseIn.c:182 py/obj.c:420 @@ -475,7 +471,7 @@ msgstr "El canal EXTINT ya está siendo utilizado" #: ports/atmel-samd/common-hal/rtc/RTC.c:101 msgid "calibration value out of range +/-127" -msgstr "Valor de calibración fuera de rango +/-127" +msgstr "Valor de calibración fuera del rango +/-127" #: ports/atmel-samd/common-hal/storage/__init__.c:48 msgid "Cannot remount '/' when USB is active." @@ -503,11 +499,11 @@ msgstr "Error USB" #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" -msgstr "Pin %q no tiene capacidades ADC" +msgstr "Pin %q no tiene capacidades de ADC" #: ports/esp8266/common-hal/analogio/AnalogOut.c:39 msgid "No hardware support for analog out." -msgstr "Sin soporte de hardware para salida análoga" +msgstr "Sin soporte de hardware para analog out" #: ports/esp8266/common-hal/busio/SPI.c:72 msgid "Pins not valid for SPI" @@ -527,21 +523,21 @@ msgstr "stop bits inválidos" #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:200 msgid "ESP8266 does not support pull down." -msgstr "ESP8266 no tiene soporte para pull down" +msgstr "ESP8266 no soporta pull down." #: ports/esp8266/common-hal/digitalio/DigitalInOut.c:210 msgid "GPIO16 does not support pull up." -msgstr "GPIO16 no tiene soporte para pull up." +msgstr "GPIO16 no soporta pull up." #: ports/esp8266/common-hal/microcontroller/__init__.c:66 msgid "ESP8226 does not support safe mode." -msgstr "ESP8226 no tiene soporte para modo seguro" +msgstr "ESP8226 no soporta modo seguro." #: ports/esp8266/common-hal/pulseio/PWMOut.c:54 #: ports/esp8266/common-hal/pulseio/PWMOut.c:113 #, c-format msgid "Maximum PWM frequency is %dhz." -msgstr "La frecuencia máxima del PWM es %dhz" +msgstr "La frecuencia máxima del PWM es %dhz." #: ports/esp8266/common-hal/pulseio/PWMOut.c:57 #: ports/esp8266/common-hal/pulseio/PWMOut.c:116 @@ -552,7 +548,7 @@ msgstr "La frecuencia mínima del PWM es 1hz" #, c-format msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." msgstr "" -"PWM de múltiples frecuencias no tiene soporte. El PWM ya se estableció a %dhz" +"PWM de múltiples frecuencias no soportado. El PWM ya se estableció a %dhz" #: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 #, c-format @@ -561,11 +557,11 @@ msgstr "El pin %d no soporta PWM" #: ports/esp8266/common-hal/pulseio/PulseIn.c:78 msgid "No PulseIn support for %q" -msgstr "%q no tiene soporte para PulseIn" +msgstr "Sin soporte PulseIn para %q" #: ports/esp8266/common-hal/storage/__init__.c:34 msgid "Unable to remount filesystem" -msgstr "No se pudo montar de nuevo el sistema de archivos" +msgstr "Incapaz de montar de nuevo el sistema de archivos" #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" @@ -590,7 +586,7 @@ msgstr "esperando un pin" #: ports/esp8266/machine_pin.c:284 msgid "Pin(16) doesn't support pull" -msgstr "Pin(16) no tiene soporte para pull" +msgstr "Pin(16) no soporta para pull" #: ports/esp8266/machine_pin.c:323 msgid "invalid pin" @@ -598,7 +594,7 @@ msgstr "pin inválido" #: ports/esp8266/machine_pin.c:389 msgid "pin does not have IRQ capabilities" -msgstr "pin no tiene capacidades IRQ" +msgstr "pin sin capacidades IRQ" #: ports/esp8266/machine_rtc.c:185 msgid "buffer too long" @@ -626,7 +622,7 @@ msgstr "len debe de ser múltiple de 4" #, c-format msgid "memory allocation failed, allocating %u bytes for native code" msgstr "" -"la asignación de memoria ha fallado, asignando %u bytes para código nativo" +"falló la asignación de memoria, asignando %u bytes para código nativo" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" @@ -638,11 +634,11 @@ msgstr "la frecuencia solo puede ser 80MHz o 160MHz" #: ports/esp8266/modnetwork.c:61 msgid "AP required" -msgstr "AP necesario" +msgstr "AP requerido" #: ports/esp8266/modnetwork.c:61 msgid "STA required" -msgstr "STA necesario" +msgstr "STA requerido" #: ports/esp8266/modnetwork.c:87 msgid "Cannot update i/f status" @@ -714,11 +710,11 @@ msgstr "Funcionalidad AnalogOut no soportada" #: ports/nrf/common-hal/busio/I2C.c:95 msgid "All I2C peripherals are in use" -msgstr "Todos los timers están siendo utilizados" +msgstr "Todos los timers están siendo usados" #: ports/nrf/common-hal/busio/SPI.c:115 msgid "All SPI peripherals are in use" -msgstr "Todos los timers están siendo utilizados" +msgstr "Todos los timers están siendo usados" #: ports/nrf/common-hal/busio/UART.c:48 #, c-format @@ -747,9 +743,8 @@ msgid "Can not get temperature. status: 0x%02x" msgstr "No se puede obtener la temperatura. status: 0x%02x" #: ports/nrf/common-hal/pulseio/PWMOut.c:162 -#, fuzzy msgid "All PWM peripherals are in use" -msgstr "Todos los timers están siendo utilizados" +msgstr "Todos los periféricos PWM en uso" #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." @@ -765,16 +760,16 @@ msgstr "No se puede consultar la dirección del dispositivo." #: ports/nrf/drivers/bluetooth/ble_drv.c:264 msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "No se puede agregar el UUID de 128-bits Especifico del Vendedor." +msgstr "No se puede agregar el Vendor Specific 128-bit UUID." #: ports/nrf/drivers/bluetooth/ble_drv.c:284 #: ports/nrf/drivers/bluetooth/ble_drv.c:298 msgid "Can not add Service." -msgstr "No se puede agregar el Servicio" +msgstr "No se puede agregar el Servicio." #: ports/nrf/drivers/bluetooth/ble_drv.c:373 msgid "Can not add Characteristic." -msgstr "No se puede agregar la Característica" +msgstr "No se puede agregar la Característica." #: ports/nrf/drivers/bluetooth/ble_drv.c:400 msgid "Can not apply device name in the stack." @@ -1134,7 +1129,7 @@ msgid "'%s' expects a register" msgstr "" #: py/emitinlinethumb.c:211 -#, fuzzy, c-format +#, c-format msgid "'%s' expects a special register" msgstr "ord espera un carácter" @@ -1178,7 +1173,6 @@ msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" #: py/emitinlinethumb.c:810 -#, fuzzy msgid "branch not in range" msgstr "El argumento de chr() no esta en el rango(256)" @@ -1345,14 +1339,12 @@ msgid "File exists" msgstr "" #: py/moduerrno.c:148 -#, fuzzy msgid "Unsupported operation" -msgstr "El pin %d no soporta PWM" +msgstr "Operacion no soportada" #: py/moduerrno.c:149 -#, fuzzy msgid "Invalid argument" -msgstr "argumentos inválidos" +msgstr "argumento inválido" #: py/obj.c:90 msgid "Traceback (most recent call last):\n" @@ -1424,9 +1416,8 @@ msgid "%q indices must be integers, not %s" msgstr "" #: py/obj.c:423 -#, fuzzy msgid "%q index out of range" -msgstr "struct: index fuera de rango" +msgstr "%w index fuera de rango" #: py/obj.c:455 msgid "object has no len" @@ -1438,9 +1429,8 @@ msgid "object of type '%s' has no len()" msgstr "" #: py/obj.c:496 -#, fuzzy msgid "object does not support item deletion" -msgstr "ESP8226 no soporta modo seguro" +msgstr "object no soporta supresión de item" #: py/obj.c:499 #, c-format @@ -1499,9 +1489,8 @@ msgid "full" msgstr "" #: py/objdeque.c:127 -#, fuzzy msgid "empty" -msgstr "heap vacío" +msgstr "vacío" #: py/objdict.c:314 msgid "popitem(): dictionary is empty" @@ -1512,9 +1501,8 @@ msgid "dict update sequence has wrong length" msgstr "" #: py/objfloat.c:308 py/parsenum.c:331 -#, fuzzy msgid "complex values not supported" -msgstr "script de compilación no soportado" +msgstr "valores complejos no soportados" #: py/objgenerator.c:108 msgid "can't send non-None value to a just-started generator" @@ -1545,9 +1533,8 @@ msgid "float too big" msgstr "" #: py/objint.c:328 -#, fuzzy msgid "long int not supported in this build" -msgstr "AnalogOut no es soportado por el pin dado" +msgstr "long int no soportado en esta compilación" #: py/objint.c:334 py/objint.c:340 py/objint.c:350 py/objint.c:358 msgid "small int overflow" @@ -1586,9 +1573,8 @@ msgid "can't set attribute" msgstr "" #: py/objobject.c:55 -#, fuzzy msgid "__new__ arg must be a user-type" -msgstr "heap debe ser una lista" +msgstr "__new__ arg debe ser un user-type" #: py/objrange.c:110 msgid "zero step" @@ -1599,9 +1585,8 @@ msgid "pop from an empty set" msgstr "" #: py/objslice.c:66 -#, fuzzy msgid "Length must be an int" -msgstr "heap debe ser una lista" +msgstr "Length debe ser un int" #: py/objslice.c:71 msgid "Length must be non-negative" @@ -1616,9 +1601,8 @@ msgid "Cannot subclass slice" msgstr "" #: py/objstr.c:261 -#, fuzzy msgid "bytes value out of range" -msgstr "Valor de calibración fuera de rango +/-127" +msgstr "valor de bytes fuera de rango" #: py/objstr.c:270 msgid "wrong number of arguments" @@ -1629,18 +1613,16 @@ msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" #: py/objstr.c:542 py/objstr.c:647 py/objstr.c:1744 -#, fuzzy msgid "empty separator" -msgstr "heap vacío" +msgstr "separator vacío" #: py/objstr.c:641 msgid "rsplit(None,n)" msgstr "" #: py/objstr.c:713 -#, fuzzy msgid "substring not found" -msgstr "módulo no encontrado" +msgstr "substring no encontrado" #: py/objstr.c:770 msgid "start/end indices" @@ -1681,14 +1663,12 @@ msgid "" msgstr "" #: py/objstr.c:1055 py/objstr.c:1083 -#, fuzzy msgid "tuple index out of range" -msgstr "struct: index fuera de rango" +msgstr "tuple index fuera de rango" #: py/objstr.c:1071 -#, fuzzy msgid "attributes not supported yet" -msgstr "bytes > 8 bits no soportados" +msgstr "atributos aún no soportados" #: py/objstr.c:1079 msgid "" @@ -1696,9 +1676,8 @@ msgid "" msgstr "" #: py/objstr.c:1171 -#, fuzzy msgid "invalid format specifier" -msgstr "formato inválido" +msgstr "especificador de formato inválido" #: py/objstr.c:1192 msgid "sign not allowed in string format specifier" @@ -1736,9 +1715,8 @@ msgid "incomplete format key" msgstr "" #: py/objstr.c:1482 -#, fuzzy msgid "incomplete format" -msgstr "formato inválido" +msgstr "formato incompleto" #: py/objstr.c:1490 msgid "not enough arguments for format string" @@ -1776,9 +1754,8 @@ msgid "string indices must be integers, not %s" msgstr "" #: py/objstrunicode.c:145 py/objstrunicode.c:164 -#, fuzzy msgid "string index out of range" -msgstr "struct: index fuera de rango" +msgstr "string index fuera de rango" #: py/objtype.c:358 msgid "__init__() should return None" @@ -1827,9 +1804,8 @@ msgid "type '%q' is not an acceptable base type" msgstr "" #: py/objtype.c:1137 -#, fuzzy msgid "multiple inheritance not supported" -msgstr "operación I2C no soportada" +msgstr "herencia multiple no soportada" #: py/objtype.c:1164 msgid "multiple bases have instance lay-out conflict" @@ -1848,14 +1824,12 @@ msgid "issubclass() arg 1 must be a class" msgstr "" #: py/parse.c:726 -#, fuzzy msgid "constant must be an integer" -msgstr "heap debe ser una lista" +msgstr "constant debe ser un entero" #: py/parse.c:868 -#, fuzzy msgid "Unable to init parser" -msgstr "No se pudo encontrar un GCLK disponible" +msgstr "Incapaz de inicializar el parser" #: py/parse.c:1170 msgid "unexpected indent" @@ -1871,7 +1845,7 @@ msgstr "" #: py/parsenum.c:151 msgid "invalid syntax for integer" -msgstr "formato inválido" +msgstr "sintaxis inválido para entero" #: py/parsenum.c:155 #, c-format @@ -1880,11 +1854,11 @@ msgstr "" #: py/parsenum.c:339 msgid "invalid syntax for number" -msgstr "argumentos inválidos" +msgstr "sintaxis inválido para número" #: py/parsenum.c:342 msgid "decimal numbers not supported" -msgstr "bytes > 8 bits no son soportados" +msgstr "números decimales no soportados" #: py/persistentcode.c:223 msgid "" @@ -1898,7 +1872,7 @@ msgstr "" #: py/runtime.c:206 msgid "name not defined" -msgstr "módulo no encontrado" +msgstr "name no definido" #: py/runtime.c:209 msgid "name '%q' is not defined" @@ -1973,9 +1947,8 @@ msgid "exceptions must derive from BaseException" msgstr "" #: py/runtime.c:1430 -#, fuzzy msgid "cannot import name %q" -msgstr "ningún módulo se llama '%q'" +msgstr "no se puede importar name '%q'" #: py/runtime.c:1535 msgid "memory allocation failed, heap is locked" @@ -1995,9 +1968,8 @@ msgid "object not in sequence" msgstr "" #: py/stream.c:96 -#, fuzzy msgid "stream operation not supported" -msgstr "operación I2C no soportada" +msgstr "operación stream no soportada" #: py/vm.c:255 msgid "local variable referenced before assignment" @@ -2144,7 +2116,6 @@ msgid "stop must be 1 or 2" msgstr "" #: shared-bindings/digitalio/DigitalInOut.c:211 -#, fuzzy msgid "Invalid direction." msgstr "Dirección inválida." @@ -2305,9 +2276,8 @@ msgid "index must be int" msgstr "" #: shared-bindings/pulseio/PulseIn.c:293 -#, fuzzy msgid "Read-only" -msgstr "Solo lectura" +msgstr "Solo-lectura" #: shared-bindings/pulseio/PulseOut.c:134 msgid "Array must contain halfwords (type 'H')" @@ -2472,14 +2442,12 @@ msgid "Group full" msgstr "" #: shared-module/displayio/Group.c:48 -#, fuzzy msgid "Group empty" -msgstr "heap vacío" +msgstr "Group vacío" #: shared-module/displayio/OnDiskBitmap.c:49 -#, fuzzy msgid "Invalid BMP file" -msgstr "pin inválido" +msgstr "Archivo BMP inválido" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format -- cgit v1.2.3 From f4940c9aec2ac73086efe18fbc57151f55c85981 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 16 Jul 2018 14:44:20 +0200 Subject: nrf: Move the UUID class from ubluepy to the shared bleio module Also added a UUIDType enum-like class for determining UUID type. --- ports/nrf/Makefile | 9 +- ports/nrf/common-hal/bleio/UUID.c | 125 +++++++++++++ ports/nrf/common-hal/bleio/UUID.h | 41 ++++ ports/nrf/drivers/bluetooth/ble_drv.c | 4 +- ports/nrf/drivers/bluetooth/ble_uart.c | 18 +- ports/nrf/modules/ubluepy/modubluepy.c | 2 - ports/nrf/modules/ubluepy/modubluepy.h | 20 +- ports/nrf/modules/ubluepy/ubluepy_characteristic.c | 3 +- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 10 +- ports/nrf/modules/ubluepy/ubluepy_service.c | 8 +- ports/nrf/modules/ubluepy/ubluepy_uuid.c | 174 ----------------- shared-bindings/bleio/UUID.c | 208 +++++++++++++++++++++ shared-bindings/bleio/UUID.h | 39 ++++ shared-bindings/bleio/UUIDType.c | 75 ++++++++ shared-bindings/bleio/UUIDType.h | 46 +++++ shared-bindings/bleio/__init__.c | 14 +- 16 files changed, 581 insertions(+), 215 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/UUID.c create mode 100644 ports/nrf/common-hal/bleio/UUID.h delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_uuid.c create mode 100644 shared-bindings/bleio/UUID.c create mode 100644 shared-bindings/bleio/UUID.h create mode 100644 shared-bindings/bleio/UUIDType.c create mode 100644 shared-bindings/bleio/UUIDType.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8b84f43df..3cb7b2035 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -132,7 +132,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/ubluepy_peripheral.c \ ubluepy/ubluepy_service.c \ ubluepy/ubluepy_characteristic.c \ - ubluepy/ubluepy_uuid.c \ ubluepy/ubluepy_delegate.c \ ubluepy/ubluepy_constants.c \ ubluepy/ubluepy_descriptor.c \ @@ -168,7 +167,8 @@ SRC_COMMON_HAL += \ ifneq ($(SD), ) SRC_COMMON_HAL += \ bleio/__init__.c \ - bleio/Adapter.c + bleio/Adapter.c \ + bleio/UUID.c endif # These don't have corresponding files in each port but are still located in @@ -183,6 +183,11 @@ SRC_BINDINGS_ENUMS = \ math/__init__.c \ util.c +ifneq ($(SD), ) +SRC_BINDINGS_ENUMS += \ + bleio/UUIDType.c +endif + SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ $(addprefix common-hal/, $(SRC_COMMON_HAL)) diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c new file mode 100644 index 000000000..e655589a6 --- /dev/null +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "ble_drv.h" +#include "common-hal/bleio/UUID.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/UUID.h" + +#define UUID_STR_16BIT_LEN 6 +#define UUID_STR_128BIT_LEN 36 + +static uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { + return unichar_xdigit_value(nibble1) | + (unichar_xdigit_value(nibble2) << 4); +} + +void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid) { + if (MP_OBJ_IS_INT(*uuid)) { + self->type = UUID_TYPE_16BIT; + + self->value[1] = (mp_obj_get_int(*uuid) >> 8) & 0xFF; + self->value[0] = (mp_obj_get_int(*uuid) >> 0) & 0xFF; + return; + } + + if (MP_OBJ_IS_STR(*uuid)) { + GET_STR_DATA_LEN(*uuid, str_data, str_len); + + if (str_len == UUID_STR_16BIT_LEN) { + self->type = UUID_TYPE_16BIT; + + self->value[0] = xdigit_8b_value(str_data[5], str_data[4]); + self->value[1] = xdigit_8b_value(str_data[3], str_data[2]); + } else if (str_len == UUID_STR_128BIT_LEN) { + self->type = UUID_TYPE_128BIT; + + uint8_t buffer[16]; + buffer[0] = xdigit_8b_value(str_data[35], str_data[34]); + buffer[1] = xdigit_8b_value(str_data[33], str_data[32]); + buffer[2] = xdigit_8b_value(str_data[31], str_data[30]); + buffer[3] = xdigit_8b_value(str_data[29], str_data[28]); + buffer[4] = xdigit_8b_value(str_data[27], str_data[26]); + buffer[5] = xdigit_8b_value(str_data[25], str_data[24]); + + // 23 '-' + buffer[6] = xdigit_8b_value(str_data[22], str_data[21]); + buffer[7] = xdigit_8b_value(str_data[20], str_data[19]); + + // 18 '-' + buffer[8] = xdigit_8b_value(str_data[17], str_data[16]); + buffer[9] = xdigit_8b_value(str_data[15], str_data[14]); + + // 13 '-' + buffer[10] = xdigit_8b_value(str_data[12], str_data[11]); + buffer[11] = xdigit_8b_value(str_data[10], str_data[9]); + + // 8 '-' + self->value[0] = xdigit_8b_value(str_data[7], str_data[6]); + self->value[1] = xdigit_8b_value(str_data[5], str_data[4]); + + buffer[14] = xdigit_8b_value(str_data[3], str_data[2]); + buffer[15] = xdigit_8b_value(str_data[1], str_data[0]); + + ble_drv_uuid_add_vs(buffer, &self->uuid_vs_idx); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Invalid UUID string length")); + } + + return; + } + + // deep copy + if (MP_OBJ_IS_TYPE(*uuid, &bleio_uuid_type)) { + bleio_uuid_obj_t *other = MP_OBJ_TO_PTR(*uuid); + self->type = other->type; + self->uuid_vs_idx = other->uuid_vs_idx; + self->value[0] = other->value[0]; + self->value[1] = other->value[1]; + + return; + } + + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Invalid UUID parameter")); +} + +void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { + if (self->type == UUID_TYPE_16BIT) { + mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", + self->value[1], self->value[0]); + } else { + mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", + self->value[1], self->value[0], self->uuid_vs_idx); + } +} + +bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self) { + return self->type; +} diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h new file mode 100644 index 000000000..b919fec28 --- /dev/null +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H + +#include "py/obj.h" +#include "shared-bindings/bleio/UUIDType.h" + +typedef struct { + mp_obj_base_t base; + bleio_uuid_type_t type; + uint8_t uuid_vs_idx; + uint8_t value[2]; +} bleio_uuid_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 3f21f8c49..81d2a8ece 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -430,11 +430,11 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; - if (p_service->p_uuid->type == UBLUEPY_UUID_16_BIT) { + if (p_service->p_uuid->type == UUID_TYPE_16BIT) { type_16bit_present = true; } - if (p_service->p_uuid->type == UBLUEPY_UUID_128_BIT) { + if (p_service->p_uuid->type == UUID_TYPE_128BIT) { type_128bit_present = true; } } diff --git a/ports/nrf/drivers/bluetooth/ble_uart.c b/ports/nrf/drivers/bluetooth/ble_uart.c index 52c042f7b..b1d54eefa 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.c +++ b/ports/nrf/drivers/bluetooth/ble_uart.c @@ -34,21 +34,21 @@ #if MICROPY_PY_BLE_NUS -static ubluepy_uuid_obj_t uuid_obj_service = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, +static bleio_uuid_obj_t uuid_obj_service = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, .value = {0x01, 0x00} }; -static ubluepy_uuid_obj_t uuid_obj_char_tx = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, +static bleio_uuid_obj_t uuid_obj_char_tx = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, .value = {0x03, 0x00} }; -static ubluepy_uuid_obj_t uuid_obj_char_rx = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, +static bleio_uuid_obj_t uuid_obj_char_rx = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, .value = {0x02, 0x00} }; diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index b306c065b..b4831e4f9 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -30,7 +30,6 @@ extern const mp_obj_type_t ubluepy_peripheral_type; extern const mp_obj_type_t ubluepy_service_type; -extern const mp_obj_type_t ubluepy_uuid_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_delegate_type; extern const mp_obj_type_t ubluepy_constants_type; @@ -50,7 +49,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&ubluepy_scan_entry_type) }, #endif { MP_ROM_QSTR(MP_QSTR_DefaultDelegate), MP_ROM_PTR(&ubluepy_delegate_type) }, - { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&ubluepy_uuid_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&ubluepy_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_constants), MP_ROM_PTR(&ubluepy_constants_type) }, diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index 83d86c5df..6c207b8c9 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -71,9 +71,9 @@ p.advertise(device_name="micr", services=[s]) */ +#include "common-hal/bleio/UUID.h" #include "py/obj.h" -extern const mp_obj_type_t ubluepy_uuid_type; extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_peripheral_type; @@ -82,11 +82,6 @@ extern const mp_obj_type_t ubluepy_scan_entry_type; extern const mp_obj_type_t ubluepy_constants_type; extern const mp_obj_type_t ubluepy_constants_ad_types_type; -typedef enum { - UBLUEPY_UUID_16_BIT = 1, - UBLUEPY_UUID_128_BIT -} ubluepy_uuid_type_t; - typedef enum { UBLUEPY_SERVICE_PRIMARY = 1, UBLUEPY_SERVICE_SECONDARY = 2 @@ -106,13 +101,6 @@ typedef enum { UBLUEPY_ROLE_CENTRAL } ubluepy_role_type_t; -typedef struct _ubluepy_uuid_obj_t { - mp_obj_base_t base; - ubluepy_uuid_type_t type; - uint8_t value[2]; - uint8_t uuid_vs_idx; -} ubluepy_uuid_obj_t; - typedef struct _ubluepy_peripheral_obj_t { mp_obj_base_t base; ubluepy_role_type_t role; @@ -127,7 +115,7 @@ typedef struct _ubluepy_service_obj_t { mp_obj_base_t base; uint16_t handle; uint8_t type; - ubluepy_uuid_obj_t * p_uuid; + bleio_uuid_obj_t * p_uuid; ubluepy_peripheral_obj_t * p_periph; mp_obj_t char_list; uint16_t start_handle; @@ -137,7 +125,7 @@ typedef struct _ubluepy_service_obj_t { typedef struct _ubluepy_characteristic_obj_t { mp_obj_base_t base; uint16_t handle; - ubluepy_uuid_obj_t * p_uuid; + bleio_uuid_obj_t * p_uuid; uint16_t service_handle; uint16_t user_desc_handle; uint16_t cccd_handle; @@ -151,7 +139,7 @@ typedef struct _ubluepy_characteristic_obj_t { typedef struct _ubluepy_descriptor_obj_t { mp_obj_base_t base; uint16_t handle; - ubluepy_uuid_obj_t * p_uuid; + bleio_uuid_obj_t * p_uuid; } ubluepy_descriptor_obj_t; typedef struct _ubluepy_delegate_obj_t { diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c index 0935615a5..e0259fb06 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c @@ -32,6 +32,7 @@ #include "modubluepy.h" #include "ble_drv.h" +#include "shared-bindings/bleio/UUID.h" STATIC void ubluepy_characteristic_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { ubluepy_characteristic_obj_t * self = (ubluepy_characteristic_obj_t *)o; @@ -60,7 +61,7 @@ STATIC mp_obj_t ubluepy_characteristic_make_new(const mp_obj_type_t *type, size_ return MP_OBJ_FROM_PTR(s); } - if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { + if (MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); // (void)sd_characterstic_add(s); } else { diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 7b6b315a9..6fced1695 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -33,6 +33,8 @@ #if MICROPY_PY_UBLUEPY #include "ble_drv.h" +#include "common-hal/bleio/UUID.h" +#include "shared-bindings/bleio/UUID.h" STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { ubluepy_peripheral_obj_t * self = (ubluepy_peripheral_obj_t *)o; @@ -294,8 +296,8 @@ void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_d ubluepy_service_obj_t * p_service = m_new_obj(ubluepy_service_obj_t); p_service->base.type = &ubluepy_service_type; - ubluepy_uuid_obj_t * p_uuid = m_new_obj(ubluepy_uuid_obj_t); - p_uuid->base.type = &ubluepy_uuid_type; + bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); + p_uuid->base.type = &bleio_uuid_type; p_service->p_uuid = p_uuid; @@ -317,8 +319,8 @@ void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data ubluepy_characteristic_obj_t * p_char = m_new_obj(ubluepy_characteristic_obj_t); p_char->base.type = &ubluepy_characteristic_type; - ubluepy_uuid_obj_t * p_uuid = m_new_obj(ubluepy_uuid_obj_t); - p_uuid->base.type = &ubluepy_uuid_type; + bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); + p_uuid->base.type = &bleio_uuid_type; p_char->p_uuid = p_uuid; diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c index 59b81234f..69d98bb7e 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ b/ports/nrf/modules/ubluepy/ubluepy_service.c @@ -33,6 +33,8 @@ #include "modubluepy.h" #include "ble_drv.h" +#include "common-hal/bleio/UUID.h" +#include "shared-bindings/bleio/UUID.h" STATIC void ubluepy_service_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { ubluepy_service_obj_t * self = (ubluepy_service_obj_t *)o; @@ -62,7 +64,7 @@ STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_arg return MP_OBJ_FROM_PTR(s); } - if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { + if (MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); uint8_t type = args[ARG_NEW_TYPE].u_int; @@ -124,10 +126,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_service_get_chars_obj, service_get_char /// STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) { ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_uuid_obj_t * p_uuid = MP_OBJ_TO_PTR(uuid); + bleio_uuid_obj_t * p_uuid = MP_OBJ_TO_PTR(uuid); // validate that there is an UUID object passed in as parameter - if (!(MP_OBJ_IS_TYPE(uuid, &ubluepy_uuid_type))) { + if (!(MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type))) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("Invalid UUID parameter"))); } diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c deleted file mode 100644 index b45494e41..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/misc.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_uuid_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_uuid_obj_t * self = (ubluepy_uuid_obj_t *)o; - if (self->type == UBLUEPY_UUID_16_BIT) { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->value[1], self->value[0]); - } else { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", - self->value[1], self->value[0], self->uuid_vs_idx); - } -} - -STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_uuid_obj_t *s = m_new_obj(ubluepy_uuid_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - if (uuid_obj == MP_OBJ_NULL) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_INT(uuid_obj)) { - s->type = UBLUEPY_UUID_16_BIT; - s->value[1] = (((uint16_t)mp_obj_get_int(uuid_obj)) >> 8) & 0xFF; - s->value[0] = ((uint8_t)mp_obj_get_int(uuid_obj)) & 0xFF; - } else if (MP_OBJ_IS_STR(uuid_obj)) { - GET_STR_DATA_LEN(uuid_obj, str_data, str_len); - if (str_len == 6) { // Assume hex digit prefixed with 0x - s->type = UBLUEPY_UUID_16_BIT; - s->value[0] = unichar_xdigit_value(str_data[5]); - s->value[0] += unichar_xdigit_value(str_data[4]) << 4; - s->value[1] = unichar_xdigit_value(str_data[3]); - s->value[1] += unichar_xdigit_value(str_data[2]) << 4; - } else if (str_len == 36) { - s->type = UBLUEPY_UUID_128_BIT; - uint8_t buffer[16]; - buffer[0] = unichar_xdigit_value(str_data[35]); - buffer[0] += unichar_xdigit_value(str_data[34]) << 4; - buffer[1] = unichar_xdigit_value(str_data[33]); - buffer[1] += unichar_xdigit_value(str_data[32]) << 4; - buffer[2] = unichar_xdigit_value(str_data[31]); - buffer[2] += unichar_xdigit_value(str_data[30]) << 4; - buffer[3] = unichar_xdigit_value(str_data[29]); - buffer[3] += unichar_xdigit_value(str_data[28]) << 4; - buffer[4] = unichar_xdigit_value(str_data[27]); - buffer[4] += unichar_xdigit_value(str_data[26]) << 4; - buffer[5] = unichar_xdigit_value(str_data[25]); - buffer[5] += unichar_xdigit_value(str_data[24]) << 4; - // 23 '-' - buffer[6] = unichar_xdigit_value(str_data[22]); - buffer[6] += unichar_xdigit_value(str_data[21]) << 4; - buffer[7] = unichar_xdigit_value(str_data[20]); - buffer[7] += unichar_xdigit_value(str_data[19]) << 4; - // 18 '-' - buffer[8] = unichar_xdigit_value(str_data[17]); - buffer[8] += unichar_xdigit_value(str_data[16]) << 4; - buffer[9] = unichar_xdigit_value(str_data[15]); - buffer[9] += unichar_xdigit_value(str_data[14]) << 4; - // 13 '-' - buffer[10] = unichar_xdigit_value(str_data[12]); - buffer[10] += unichar_xdigit_value(str_data[11]) << 4; - buffer[11] = unichar_xdigit_value(str_data[10]); - buffer[11] += unichar_xdigit_value(str_data[9]) << 4; - // 8 '-' - // 16-bit field - s->value[0] = unichar_xdigit_value(str_data[7]); - s->value[0] += unichar_xdigit_value(str_data[6]) << 4; - s->value[1] = unichar_xdigit_value(str_data[5]); - s->value[1] += unichar_xdigit_value(str_data[4]) << 4; - - buffer[14] = unichar_xdigit_value(str_data[3]); - buffer[14] += unichar_xdigit_value(str_data[2]) << 4; - buffer[15] = unichar_xdigit_value(str_data[1]); - buffer[15] += unichar_xdigit_value(str_data[0]) << 4; - - ble_drv_uuid_add_vs(buffer, &s->uuid_vs_idx); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID string length"))); - } - } else if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { - // deep copy instance - ubluepy_uuid_obj_t * p_old = MP_OBJ_TO_PTR(uuid_obj); - s->type = p_old->type; - s->value[0] = p_old->value[0]; - s->value[1] = p_old->value[1]; - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - return MP_OBJ_FROM_PTR(s); -} - -/// \method binVal() -/// Get binary value of the 16 or 128 bit UUID. Returned as bytearray type. -/// -STATIC mp_obj_t uuid_bin_val(mp_obj_t self_in) { - ubluepy_uuid_obj_t * self = MP_OBJ_TO_PTR(self_in); - - // TODO: Extend the uint16 byte value to 16 byte if 128-bit, - // also encapsulate it in a bytearray. For now, return - // the uint16_t field of the UUID. - return MP_OBJ_NEW_SMALL_INT(self->value[0] | self->value[1] << 8); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_uuid_bin_val_obj, uuid_bin_val); - -STATIC const mp_rom_map_elem_t ubluepy_uuid_locals_dict_table[] = { -#if 0 - { MP_ROM_QSTR(MP_QSTR_getCommonName), MP_ROM_PTR(&ubluepy_uuid_get_common_name_obj) }, -#endif - // Properties - { MP_ROM_QSTR(MP_QSTR_binVal), MP_ROM_PTR(&ubluepy_uuid_bin_val_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_uuid_locals_dict, ubluepy_uuid_locals_dict_table); - -const mp_obj_type_t ubluepy_uuid_type = { - { &mp_type_type }, - .name = MP_QSTR_UUID, - .print = ubluepy_uuid_print, - .make_new = ubluepy_uuid_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_uuid_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c new file mode 100644 index 000000000..0523e918f --- /dev/null +++ b/shared-bindings/bleio/UUID.c @@ -0,0 +1,208 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/UUID.h" + +enum { + ServiceUuidGenericAccess = 0x1800, + ServiceUuidGenericAttribute = 0x1801, + ServiceUuidImmediateAlert = 0x1802, + ServiceUuidLinkLoss = 0x1803, + ServiceUuidTxPower = 0x1804, + ServiceUuidCurrentTimeServiceService = 0x1805, + ServiceUuidReferenceTimeUpdateService = 0x1806, + ServiceUuidNextDSTChangeService = 0x1807, + ServiceUuidGlucose = 0x1808, + ServiceUuidHealthThermometer = 0x1809, + ServiceUuidDeviceInformation = 0x180A, + ServiceUuidHeartRate = 0x180D, + ServiceUuidPhoneAlertStatusService = 0x180E, + ServiceUuidBatteryService = 0x180F, + ServiceUuidBloodPressure = 0x1810, + ServiceUuidAlertNotificationService = 0x1811, + ServiceUuidHumanInterfaceDevice = 0x1812, + ServiceUuidScanParameters = 0x1813, + ServiceUuidRunningSpeedAndCadence = 0x1814, + ServiceUuidAutomationIO = 0x1815, + ServiceUuidCyclingSpeedAndCadence = 0x1816, + ServiceUuidCyclingPower = 0x1818, + ServiceUuidLocationAndNavigation = 0x1819, + ServiceUuidEnvironmentalSensing = 0x181A, + ServiceUuidBodyComposition = 0x181B, + ServiceUuidUserData = 0x181C, + ServiceUuidWeightScale = 0x181D, + ServiceUuidBondManagementService = 0x181E, + ServiceUuidContinuousGlucoseMonitoring = 0x181F, + ServiceUuidInternetProtocolSupportService = 0x1820, + ServiceUuidIndoorPositioning = 0x1821, + ServiceUuidPulseOximeterService = 0x1822, + ServiceUuidHTTPProxy = 0x1823, + ServiceUuidTransportDiscovery = 0x1824, + ServiceUuidObjectTransferService = 0x1825, + ServiceUuidFitnessMachine = 0x1826, + ServiceUuidMeshProvisioningService = 0x1827, + ServiceUuidMeshProxyService = 0x1828, + ServiceUuidReconnectionConfiguration = 0x1829, +}; + +//| .. currentmodule:: bleio +//| +//| :class:`UUID` -- BLE UUID +//| ========================================================= +//| +//| Encapsulates both 16-bit and 128-bit UUIDs. Can be used for services, +//| characteristics, descriptors and more. +//| + +//| .. class:: UUID(uuid) +//| +//| Create a new UUID object encapsulating the uuid value. +//| The value itself can be one of: +//| +//| - a `int` value in range of 0 to 0xFFFF +//| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit +//| - another UUID object +//| +//| :param uuid: The uuid to encapsulate +//| + +//| .. attribute:: type +//| +//| The UUID type. One of: +//| +//| - `bleio.UUIDType.TYPE_16BIT` +//| - `bleio.UUIDType.TYPE_128BIT` +//| +STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); + self->base.type = &bleio_uuid_type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + 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); + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + common_hal_bleio_uuid_construct(self, &uuid); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_uuid_print(self, print); +} + +STATIC mp_obj_t bleio_uuid_get_type(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); + if (type == UUID_TYPE_16BIT) { + return (mp_obj_t)&bleio_uuidtype_16bit_obj; + } + + if (type == UUID_TYPE_128BIT) { + return (mp_obj_t)&bleio_uuidtype_128bit_obj; + } + + return (mp_obj_t)&mp_const_none_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_type_obj, bleio_uuid_get_type); + +const mp_obj_property_t bleio_uuid_type_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_type_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_uuid_type_obj) }, + + // Static variables + { MP_ROM_QSTR(MP_QSTR_SERVICE_GENERIC_ACCESS), MP_ROM_INT(ServiceUuidGenericAccess) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_GENERIC_ATTRIBUTE), MP_ROM_INT(ServiceUuidGenericAttribute) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_IMMEDIATE_ALERT), MP_ROM_INT(ServiceUuidImmediateAlert) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_LINK_LOSS), MP_ROM_INT(ServiceUuidLinkLoss) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_TX_POWER), MP_ROM_INT(ServiceUuidTxPower) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_CURRENT_TIME_SERVICE), MP_ROM_INT(ServiceUuidCurrentTimeServiceService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_REFERENCE_TIME_UPDATE_SERVICE), MP_ROM_INT(ServiceUuidReferenceTimeUpdateService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_NEXT_DST_CHANGE_SERVICE), MP_ROM_INT(ServiceUuidNextDSTChangeService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_GLUCOSE), MP_ROM_INT(ServiceUuidGlucose) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_HEALTH_THERMOMETER), MP_ROM_INT(ServiceUuidHealthThermometer) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DEVICE_INFORMATION), MP_ROM_INT(ServiceUuidDeviceInformation) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_HEART_RATE), MP_ROM_INT(ServiceUuidHeartRate) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_PHONE_ALERT_STATUS_SERVICE), MP_ROM_INT(ServiceUuidPhoneAlertStatusService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_BATTERY_SERVICE), MP_ROM_INT(ServiceUuidBatteryService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_BLOOD_PRESSURE), MP_ROM_INT(ServiceUuidBloodPressure) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_ALERT_NOTIFICATION_SERVICE), MP_ROM_INT(ServiceUuidAlertNotificationService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_HUMAN_INTERFACE_DEVICE), MP_ROM_INT(ServiceUuidHumanInterfaceDevice) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_SCAN_PARAMETERS), MP_ROM_INT(ServiceUuidScanParameters) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_RUNNING_SPEED_AND_CADENCE), MP_ROM_INT(ServiceUuidRunningSpeedAndCadence) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_AUTOMATION_IO), MP_ROM_INT(ServiceUuidAutomationIO) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_CYCLING_SPEED_AND_CADENCE), MP_ROM_INT(ServiceUuidCyclingSpeedAndCadence) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_CYCLING_POWER), MP_ROM_INT(ServiceUuidCyclingPower) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_LOCATION_AND_NAVIGATION), MP_ROM_INT(ServiceUuidLocationAndNavigation) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_ENVIRONMENTAL_SENSING), MP_ROM_INT(ServiceUuidEnvironmentalSensing) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_BODY_COMPOSITION), MP_ROM_INT(ServiceUuidBodyComposition) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_USER_DATA), MP_ROM_INT(ServiceUuidUserData) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_WEIGHT_SCALE), MP_ROM_INT(ServiceUuidWeightScale) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_BOND_MANAGEMENT_SERVICE), MP_ROM_INT(ServiceUuidBondManagementService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_CONTINUOUS_GLUCOSE_MONITORING), MP_ROM_INT(ServiceUuidContinuousGlucoseMonitoring) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_INTERNET_PROTOCOL_SUPPORT_SERVICE), MP_ROM_INT(ServiceUuidInternetProtocolSupportService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_INDOOR_POSITIONING), MP_ROM_INT(ServiceUuidIndoorPositioning) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_PULSE_OXIMETER_SERVICE), MP_ROM_INT(ServiceUuidPulseOximeterService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_HTTP_PROXY), MP_ROM_INT(ServiceUuidHTTPProxy) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_TRANSPORT_DISCOVERY), MP_ROM_INT(ServiceUuidTransportDiscovery) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_OBJECT_TRANSFER_SERVICE), MP_ROM_INT(ServiceUuidObjectTransferService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_FITNESS_MACHINE), MP_ROM_INT(ServiceUuidFitnessMachine) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_MESH_PROVISIONING_SERVICE), MP_ROM_INT(ServiceUuidMeshProvisioningService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_MESH_PROXY_SERVICE), MP_ROM_INT(ServiceUuidMeshProxyService) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_RECONNECTION_CONFIGURATION), MP_ROM_INT(ServiceUuidReconnectionConfiguration) } +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); + +const mp_obj_type_t bleio_uuid_type = { + { &mp_type_type }, + .name = MP_QSTR_UUID, + .print = bleio_uuid_print, + .make_new = bleio_uuid_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict +}; diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h new file mode 100644 index 000000000..d6fcbac1b --- /dev/null +++ b/shared-bindings/bleio/UUID.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H + +#include "common-hal/bleio/UUID.h" +#include "shared-bindings/bleio/UUIDType.h" + +extern const mp_obj_type_t bleio_uuid_type; + +extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid); +extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); +extern bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H diff --git a/shared-bindings/bleio/UUIDType.c b/shared-bindings/bleio/UUIDType.c new file mode 100644 index 000000000..e36d1f06d --- /dev/null +++ b/shared-bindings/bleio/UUIDType.c @@ -0,0 +1,75 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "shared-bindings/bleio/UUIDType.h" + +//| .. currentmodule:: bleio +//| +//| :class:`UUIDType` -- defines the type of a BLE UUID +//| ============================================================= +//| +//| .. class:: bleio.UUIDType +//| +//| Enum-like class to define the type of a BLE UUID. +//| +//| .. data:: TYPE_16BIT +//| +//| The UUID is 16-bit +//| +//| .. data:: TYPE_128BIT +//| +//| The UUID is 128-bit +//| +const mp_obj_type_t bleio_uuidtype_type; + +const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj = { + { &bleio_uuidtype_type }, +}; + +const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj = { + { &bleio_uuidtype_type }, +}; + +STATIC const mp_rom_map_elem_t bleio_uuidtype_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TYPE_16BIT), MP_ROM_PTR(&bleio_uuidtype_16bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_TYPE_128BIT), MP_ROM_PTR(&bleio_uuidtype_128bit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bleio_uuidtype_locals_dict, bleio_uuidtype_locals_dict_table); + +STATIC void bleio_uuidtype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr type = MP_QSTR_TYPE_128BIT; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_uuidtype_16bit_obj)) { + type = MP_QSTR_TYPE_16BIT; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_UUIDType, type); +} + +const mp_obj_type_t bleio_uuidtype_type = { + { &mp_type_type }, + .name = MP_QSTR_UUIDType, + .print = bleio_uuidtype_print, + .locals_dict = (mp_obj_t)&bleio_uuidtype_locals_dict, +}; diff --git a/shared-bindings/bleio/UUIDType.h b/shared-bindings/bleio/UUIDType.h new file mode 100644 index 000000000..87bbf9b53 --- /dev/null +++ b/shared-bindings/bleio/UUIDType.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H + +#include "py/obj.h" + +typedef enum { + UUID_TYPE_16BIT, + UUID_TYPE_128BIT +} bleio_uuid_type_t; + +extern const mp_obj_type_t bleio_uuidtype_type; + +typedef struct { + mp_obj_base_t base; +} bleio_uuidtype_obj_t; + +extern const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj; +extern const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 475fb395a..f59f1654b 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -27,6 +27,8 @@ #include "py/obj.h" #include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/bleio/UUIDType.h" //| :mod:`bleio` --- Bluetooth Low Energy functionality //| ================================================================ @@ -43,6 +45,8 @@ //| :maxdepth: 3 //| //| Adapter +//| UUID +//| UUIDType //| //| .. attribute:: adapter //| @@ -52,8 +56,14 @@ //| STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, - { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + + // Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); -- cgit v1.2.3 From 20b8d5169d02321c267cdb234c492ee92c321032 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 16 Jul 2018 16:31:28 +0200 Subject: nrf: Move the Descriptor class from ubluepy to the shared bleio module --- ports/nrf/Makefile | 2 +- ports/nrf/common-hal/bleio/Descriptor.c | 45 +++++++ ports/nrf/common-hal/bleio/Descriptor.h | 40 ++++++ ports/nrf/modules/ubluepy/modubluepy.c | 3 - ports/nrf/modules/ubluepy/modubluepy.h | 6 - ports/nrf/modules/ubluepy/ubluepy_descriptor.c | 82 ------------ shared-bindings/bleio/Descriptor.c | 171 +++++++++++++++++++++++++ shared-bindings/bleio/Descriptor.h | 40 ++++++ shared-bindings/bleio/__init__.c | 3 + 9 files changed, 300 insertions(+), 92 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Descriptor.c create mode 100644 ports/nrf/common-hal/bleio/Descriptor.h delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_descriptor.c create mode 100644 shared-bindings/bleio/Descriptor.c create mode 100644 shared-bindings/bleio/Descriptor.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 3cb7b2035..ad9aa2fed 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -134,7 +134,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/ubluepy_characteristic.c \ ubluepy/ubluepy_delegate.c \ ubluepy/ubluepy_constants.c \ - ubluepy/ubluepy_descriptor.c \ ubluepy/ubluepy_scanner.c \ ubluepy/ubluepy_scan_entry.c \ ) @@ -168,6 +167,7 @@ ifneq ($(SD), ) SRC_COMMON_HAL += \ bleio/__init__.c \ bleio/Adapter.c \ + bleio/Descriptor.c \ bleio/UUID.c endif diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c new file mode 100644 index 000000000..9b61345fa --- /dev/null +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "common-hal/bleio/Descriptor.h" + +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { + self->uuid = uuid; +} + +void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print) { + mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", + self->uuid->value[1], self->uuid->value[0]); +} + +mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { + return self->handle; +} + +mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return self->uuid->value[0] | (self->uuid->value[1] << 8); +} diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h new file mode 100644 index 000000000..ee0886c22 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Descriptor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H + +#include "py/obj.h" +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + uint16_t handle; + bleio_uuid_obj_t *uuid; +} bleio_descriptor_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index b4831e4f9..0c02b22f2 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -52,9 +52,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&ubluepy_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_constants), MP_ROM_PTR(&ubluepy_constants_type) }, -#if MICROPY_PY_UBLUEPY_DESCRIPTOR - { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&ubluepy_descriptor_type) }, -#endif }; diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index 6c207b8c9..0ca491634 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -136,12 +136,6 @@ typedef struct _ubluepy_characteristic_obj_t { mp_obj_t value_data; } ubluepy_characteristic_obj_t; -typedef struct _ubluepy_descriptor_obj_t { - mp_obj_base_t base; - uint16_t handle; - bleio_uuid_obj_t * p_uuid; -} ubluepy_descriptor_obj_t; - typedef struct _ubluepy_delegate_obj_t { mp_obj_base_t base; } ubluepy_delegate_obj_t; diff --git a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c deleted file mode 100644 index b15301954..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/misc.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_descriptor_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_descriptor_obj_t * self = (ubluepy_descriptor_obj_t *)o; - - mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->p_uuid->value[1], self->p_uuid->value[0]); -} - -STATIC mp_obj_t ubluepy_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_descriptor_obj_t * s = m_new_obj(ubluepy_descriptor_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - (void)uuid_obj; - - return MP_OBJ_FROM_PTR(s); -} - -STATIC const mp_rom_map_elem_t ubluepy_descriptor_locals_dict_table[] = { -#if 0 - { MP_ROM_QSTR(MP_QSTR_binVal), MP_ROM_PTR(&ubluepy_descriptor_bin_val_obj) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_descriptor_locals_dict, ubluepy_descriptor_locals_dict_table); - -const mp_obj_type_t ubluepy_descriptor_type = { - { &mp_type_type }, - .name = MP_QSTR_Descriptor, - .print = ubluepy_descriptor_print, - .make_new = ubluepy_descriptor_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_descriptor_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c new file mode 100644 index 000000000..df32a00e7 --- /dev/null +++ b/shared-bindings/bleio/Descriptor.c @@ -0,0 +1,171 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/UUID.h" + +enum { + DescriptorUuidCharacteristicExtendedProperties = 0x2900, + DescriptorUuidCharacteristicUserDescription = 0x2901, + DescriptorUuidClientCharacteristicConfiguration = 0x2902, + DescriptorUuidServerCharacteristicConfiguration = 0x2903, + DescriptorUuidCharacteristicPresentationFormat = 0x2904, + DescriptorUuidCharacteristicAggregateFormat = 0x2905, + DescriptorUuidValidRange = 0x2906, + DescriptorUuidExternalReportReference = 0x2907, + DescriptorUuidReportReference = 0x2908, + DescriptorUuidNumberOfDigitals = 0x2909, + DescriptorUuidValueTriggerSetting = 0x290A, + DescriptorUuidEnvironmentalSensingConfiguration = 0x290B, + DescriptorUuidEnvironmentalSensingMeasurement = 0x290C, + DescriptorUuidEnvironmentalSensingTriggerSetting = 0x290D, + DescriptorUuidTimeTriggerSetting = 0x290E, +}; + +//| .. currentmodule:: bleio +//| +//| :class:`Descriptor` -- BLE descriptor +//| ========================================================= +//| +//| Stores information about a BLE descriptor. +//| Descriptors are encapsulated by BLE characteristics and provide contextual +//| information about the characteristic. +//| + +//| .. class:: Descriptor(uuid) +//| +//| Create a new descriptor object with the UUID uuid. +//| The value can be either of type `bleio.UUID` or any value allowed by the `bleio.UUID` constructor. + +//| .. attribute:: handle +//| +//| The descriptor handle. (read-only) +//| + +//| .. attribute:: uuid +//| +//| The descriptor uuid. (read-only) +//| +STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); + self->base.type = type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + 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); + + const mp_obj_t uuid_arg = args[ARG_uuid].u_obj; + + bleio_uuid_obj_t *uuid; + if (MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { + uuid = MP_OBJ_TO_PTR(uuid_arg); + } else { + uuid = MP_OBJ_TO_PTR(bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_arg)); + } + + common_hal_bleio_descriptor_construct(self, uuid); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_descriptor_print(self, print); +} + +STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_handle_obj, bleio_descriptor_get_handle); + +const mp_obj_property_t bleio_descriptor_handle_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_descriptor_get_handle_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + const mp_obj_t uuid = mp_obj_new_int(common_hal_bleio_descriptor_get_uuid(self)); + + return bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid); + +const mp_obj_property_t bleio_descriptor_uuid_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_descriptor_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_handle), MP_ROM_PTR(&bleio_descriptor_handle_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, + + // Static variables + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), MP_ROM_INT(DescriptorUuidCharacteristicExtendedProperties) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), MP_ROM_INT(DescriptorUuidCharacteristicUserDescription) }, + { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidClientCharacteristicConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidServerCharacteristicConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicPresentationFormat) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicAggregateFormat) }, + { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), MP_ROM_INT(DescriptorUuidValidRange) }, + { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidExternalReportReference) }, + { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidReportReference) }, + { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), MP_ROM_INT(DescriptorUuidNumberOfDigitals) }, + { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidValueTriggerSetting) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), MP_ROM_INT(DescriptorUuidEnvironmentalSensingConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), MP_ROM_INT(DescriptorUuidEnvironmentalSensingMeasurement) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidEnvironmentalSensingTriggerSetting) }, + { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidTimeTriggerSetting) } +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table); + +const mp_obj_type_t bleio_descriptor_type = { + { &mp_type_type }, + .name = MP_QSTR_Descriptor, + .print = bleio_descriptor_print, + .make_new = bleio_descriptor_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict +}; diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h new file mode 100644 index 000000000..85310d304 --- /dev/null +++ b/shared-bindings/bleio/Descriptor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H + +#include "common-hal/bleio/Descriptor.h" +#include "common-hal/bleio/UUID.h" + +extern const mp_obj_type_t bleio_descriptor_type; + +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid); +extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print); +extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); +extern mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index f59f1654b..cf627702f 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -27,6 +27,7 @@ #include "py/obj.h" #include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/UUIDType.h" @@ -45,6 +46,7 @@ //| :maxdepth: 3 //| //| Adapter +//| Descriptor //| UUID //| UUIDType //| @@ -57,6 +59,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties -- cgit v1.2.3 From d5f942a971f001d0a2fe4655f500beefe96dbd46 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Tue, 17 Jul 2018 09:34:39 +0200 Subject: bleio: Add a AddressType enum-like class --- ports/nrf/Makefile | 1 + shared-bindings/bleio/AddressType.c | 99 +++++++++++++++++++++++++++++++++++++ shared-bindings/bleio/AddressType.h | 50 +++++++++++++++++++ shared-bindings/bleio/__init__.c | 13 +++-- 4 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 shared-bindings/bleio/AddressType.c create mode 100644 shared-bindings/bleio/AddressType.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index ad9aa2fed..aebd87048 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -185,6 +185,7 @@ SRC_BINDINGS_ENUMS = \ ifneq ($(SD), ) SRC_BINDINGS_ENUMS += \ + bleio/AddressType.c \ bleio/UUIDType.c endif diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c new file mode 100644 index 000000000..4aef9feed --- /dev/null +++ b/shared-bindings/bleio/AddressType.c @@ -0,0 +1,99 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "shared-bindings/bleio/AddressType.h" + +//| .. currentmodule:: bleio +//| +//| :class:`AddressType` -- defines the type of a BLE address +//| ============================================================= +//| +//| .. class:: bleio.AddressType +//| +//| Enum-like class to define the type of a BLE address. +//| +//| .. data:: PUBLIC +//| +//| The address is public +//| +//| .. data:: RANDOM_STATIC +//| +//| The address is random static +//| +//| .. data:: RANDOM_PRIVATE_RESOLVABLE +//| +//| The address is random private resolvable +//| +//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE +//| +//| The address is private non-resolvable +//| +const mp_obj_type_t bleio_addresstype_type; + +const bleio_addresstype_obj_t bleio_addresstype_public_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = { + { &bleio_addresstype_type }, +}; + +STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table); + +STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr type = MP_QSTR_PUBLIC; + + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) { + type = MP_QSTR_RANDOM_STATIC; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) { + type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) { + type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE; + } + + mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type); +} + +const mp_obj_type_t bleio_addresstype_type = { + { &mp_type_type }, + .name = MP_QSTR_AddressType, + .print = bleio_addresstype_print, + .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict, +}; diff --git a/shared-bindings/bleio/AddressType.h b/shared-bindings/bleio/AddressType.h new file mode 100644 index 000000000..e69caffab --- /dev/null +++ b/shared-bindings/bleio/AddressType.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H + +#include "py/obj.h" + +typedef enum { + ADDRESS_PUBLIC, + ADDRESS_RANDOM_STATIC, + ADDRESS_RANDOM_PRIVATE_RESOLVABLE, + ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE +} bleio_address_type_t; + +extern const mp_obj_type_t bleio_addresstype_type; + +typedef struct { + mp_obj_base_t base; +} bleio_addresstype_obj_t; + +extern const bleio_addresstype_obj_t bleio_addresstype_public_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index cf627702f..a343d2f05 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -27,6 +27,7 @@ #include "py/obj.h" #include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/UUIDType.h" @@ -45,6 +46,7 @@ //| .. toctree:: //| :maxdepth: 3 //| +//| AddressType //| Adapter //| Descriptor //| UUID @@ -58,15 +60,16 @@ //| STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, - { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties - { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, // Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, + { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); -- cgit v1.2.3 From 345334aaf13dabbbb5fbfc1778fc34ed78907f42 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Tue, 17 Jul 2018 11:44:55 +0200 Subject: bleio: Add a new Address class Use the new in the Adapter singleton. --- ports/nrf/Makefile | 1 + ports/nrf/common-hal/bleio/Adapter.c | 15 ++- ports/nrf/modules/ubluepy/modubluepy.h | 2 - ports/nrf/modules/ubluepy/ubluepy_constants.c | 3 - shared-bindings/bleio/Adapter.c | 15 +-- shared-bindings/bleio/Adapter.h | 4 +- shared-bindings/bleio/Address.c | 167 ++++++++++++++++++++++++++ shared-bindings/bleio/Address.h | 34 ++++++ shared-bindings/bleio/AddressType.c | 2 +- shared-bindings/bleio/__init__.c | 3 + shared-module/bleio/Address.h | 40 ++++++ 11 files changed, 260 insertions(+), 26 deletions(-) create mode 100644 shared-bindings/bleio/Address.c create mode 100644 shared-bindings/bleio/Address.h create mode 100644 shared-module/bleio/Address.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index aebd87048..2de7f24bd 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -185,6 +185,7 @@ SRC_BINDINGS_ENUMS = \ ifneq ($(SD), ) SRC_BINDINGS_ENUMS += \ + bleio/Address.c \ bleio/AddressType.c \ bleio/UUIDType.c endif diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 52069e305..f4c35ac69 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -26,11 +26,12 @@ */ #include +#include #include "ble_drv.h" #include "nrfx.h" #include "nrf_error.h" -#include "py/misc.h" +#include "shared-module/bleio/Address.h" void common_hal_bleio_adapter_set_enabled(bool enabled) { if (enabled) { @@ -49,12 +50,10 @@ bool common_hal_bleio_adapter_get_enabled(void) { return ble_drv_stack_enabled(); } -void common_hal_bleio_adapter_get_address(vstr_t *vstr) { - ble_drv_addr_t address; - ble_drv_address_get(&address); +void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { + ble_drv_addr_t drv_addr; + ble_drv_address_get(&drv_addr); - vstr_printf(vstr, ""HEX2_FMT":"HEX2_FMT":"HEX2_FMT":" \ - HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", - address.addr[5], address.addr[4], address.addr[3], - address.addr[2], address.addr[1], address.addr[0]); + address->type = drv_addr.addr_type; + memcpy(address->value, drv_addr.addr, BLEIO_ADDRESS_BYTES); } diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index 0ca491634..c5fd7b6f8 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -90,10 +90,8 @@ typedef enum { typedef enum { UBLUEPY_ADDR_TYPE_PUBLIC = 0, UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1, -#if 0 UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2, UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3, -#endif } ubluepy_addr_type_t; typedef enum { diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c index 14e433e6e..e53a6f068 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ b/ports/nrf/modules/ubluepy/ubluepy_constants.c @@ -82,9 +82,6 @@ STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_EVT_GATTS_WRITE), MP_ROM_INT(80) }, { MP_ROM_QSTR(MP_QSTR_UUID_CCCD), MP_ROM_INT(0x2902) }, - { MP_ROM_QSTR(MP_QSTR_ADDR_TYPE_PUBLIC), MP_ROM_INT(UBLUEPY_ADDR_TYPE_PUBLIC) }, - { MP_ROM_QSTR(MP_QSTR_ADDR_TYPE_RANDOM_STATIC), MP_ROM_INT(UBLUEPY_ADDR_TYPE_RANDOM_STATIC) }, - { MP_ROM_QSTR(MP_QSTR_ad_types), MP_ROM_PTR(&ubluepy_constants_ad_types_type) }, }; diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c index bfe87071d..d9449d3ab 100644 --- a/shared-bindings/bleio/Adapter.c +++ b/shared-bindings/bleio/Adapter.c @@ -25,6 +25,7 @@ */ #include "py/objproperty.h" +#include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/Adapter.h" //| .. currentmodule:: bleio @@ -57,8 +58,6 @@ //| MAC address of the BLE adapter. (read-only) //| -#define BLE_ADDRESS_LEN 17 - STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled()); } @@ -81,16 +80,12 @@ const mp_obj_property_t bleio_adapter_enabled_obj = { }; STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) { - vstr_t vstr; - vstr_init(&vstr, BLE_ADDRESS_LEN); - - common_hal_bleio_adapter_get_address(&vstr); - - const mp_obj_t mac_str = mp_obj_new_str(vstr.buf, vstr.len); + mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, mp_const_none); + bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); - vstr_clear(&vstr); + common_hal_bleio_adapter_get_address(address); - return mac_str; + return obj; } MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address); diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h index 6c5d56948..fe3886e59 100644 --- a/shared-bindings/bleio/Adapter.h +++ b/shared-bindings/bleio/Adapter.h @@ -27,12 +27,12 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H -#include "py/obj.h" +#include "shared-module/bleio/Address.h" const mp_obj_type_t bleio_adapter_type; extern bool common_hal_bleio_adapter_get_enabled(void); extern void common_hal_bleio_adapter_set_enabled(bool enabled); -extern void common_hal_bleio_adapter_get_address(vstr_t *address); +extern void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c new file mode 100644 index 000000000..7ac42c740 --- /dev/null +++ b/shared-bindings/bleio/Address.c @@ -0,0 +1,167 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Address.h" +#include "shared-module/bleio/Address.h" + +#define ADDRESS_LONG_LEN 17 // XX:XX:XX:XX:XX:XX +#define ADDRESS_SHORT_LEN 12 // XXXXXXXXXXXX + +//| .. currentmodule:: bleio +//| +//| :class:`Address` -- BLE address +//| ========================================================= +//| +//| Encapsulates the address of a BLE device. +//| + +//| .. class:: Address(address) +//| +//| Create a new Address object encapsulating the address value. +//| The value itself can be one of: +//| +//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX' +//| - a `bytes` or `bytearray` containing 6 bytes +//| - another Address object +//| +//| :param address: The address to encapsulate +//| + +//| .. attribute:: type +//| +//| The address type. One of: +//| +//| - `bleio.AddressType.PUBLIC` +//| - `bleio.AddressType.RANDOM_STATIC` +//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE` +//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE` +//| +STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); + self->base.type = &bleio_address_type; + self->type = ADDRESS_PUBLIC; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_address }; + static const mp_arg_t allowed_args[] = { + { ARG_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + 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); + + const mp_obj_t address = args[ARG_address].u_obj; + + if (MP_OBJ_IS_STR(address)) { + GET_STR_DATA_LEN(address, str_data, str_len); + const bool is_long = (str_len == ADDRESS_LONG_LEN); + const bool is_short = (str_len == ADDRESS_SHORT_LEN); + + if (is_long || is_short) { + size_t i = str_len - 1; + for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { + self->value[b] = unichar_xdigit_value(str_data[i]) | + unichar_xdigit_value(str_data[i - 1]) << 4; + + i -= is_long ? 3 : 2; + } + } else { + mp_raise_ValueError("Wrong address length"); + } + } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) { + mp_buffer_info_t buf_info; + mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); + if (buf_info.len != BLEIO_ADDRESS_BYTES) { + mp_raise_ValueError("Wrong number of bytes provided"); + } + + for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { + self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b]; + } + } else if (MP_OBJ_IS_TYPE(address, &bleio_address_type)) { + // deep copy + bleio_address_obj_t *other = MP_OBJ_TO_PTR(address); + self->type = other->type; + memcpy(self->value, other->value, BLEIO_ADDRESS_BYTES); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Address('"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"')", + self->value[5], self->value[4], self->value[3], + self->value[2], self->value[1], self->value[0]); +} + +STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->type == ADDRESS_PUBLIC) { + return (mp_obj_t)&bleio_addresstype_public_obj; + } else if (self->type == ADDRESS_RANDOM_STATIC) { + return (mp_obj_t)&bleio_addresstype_random_static_obj; + } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) { + return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj; + } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) { + return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj; + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type); + +const mp_obj_property_t bleio_address_type_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_address_get_type_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table); + +const mp_obj_type_t bleio_address_type = { + { &mp_type_type }, + .name = MP_QSTR_Address, + .print = bleio_address_print, + .make_new = bleio_address_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict +}; diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h new file mode 100644 index 000000000..9c9e20968 --- /dev/null +++ b/shared-bindings/bleio/Address.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H + +#include "py/objtype.h" + +extern const mp_obj_type_t bleio_address_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c index 4aef9feed..cf2151c94 100644 --- a/shared-bindings/bleio/AddressType.c +++ b/shared-bindings/bleio/AddressType.c @@ -33,7 +33,7 @@ //| //| .. class:: bleio.AddressType //| -//| Enum-like class to define the type of a BLE address. +//| Enum-like class to define the type of a BLE address, see also `bleio.Address`. //| //| .. data:: PUBLIC //| diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index a343d2f05..570b71798 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -27,6 +27,7 @@ #include "py/obj.h" #include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/UUID.h" @@ -46,6 +47,7 @@ //| .. toctree:: //| :maxdepth: 3 //| +//| Address //| AddressType //| Adapter //| Descriptor @@ -61,6 +63,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, diff --git a/shared-module/bleio/Address.h b/shared-module/bleio/Address.h new file mode 100644 index 000000000..a520b8dd6 --- /dev/null +++ b/shared-module/bleio/Address.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H + +#include "shared-bindings/bleio/AddressType.h" + +#define BLEIO_ADDRESS_BYTES 6 + +typedef struct { + mp_obj_base_t base; + bleio_address_type_t type; + uint8_t value[BLEIO_ADDRESS_BYTES]; +} bleio_address_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H -- cgit v1.2.3 From 7390dc7dab2c5ccd34a1fa5a33e1e5241b8f9bd7 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Tue, 17 Jul 2018 17:00:37 +0200 Subject: bleio: Move ScanEntry to shared module and add a new AdvertisementData class --- ports/nrf/Makefile | 3 +- ports/nrf/drivers/bluetooth/ble_drv.c | 12 + ports/nrf/drivers/bluetooth/ble_drv.h | 2 + ports/nrf/modules/ubluepy/modubluepy.c | 2 - ports/nrf/modules/ubluepy/modubluepy.h | 10 - ports/nrf/modules/ubluepy/ubluepy_constants.c | 47 ---- ports/nrf/modules/ubluepy/ubluepy_scan_entry.c | 146 ------------ ports/nrf/modules/ubluepy/ubluepy_scanner.c | 26 +-- shared-bindings/bleio/AdvertisementData.c | 92 ++++++++ shared-bindings/bleio/AdvertisementData.h | 34 +++ shared-bindings/bleio/ScanEntry.c | 307 +++++++++++++++++++++++++ shared-bindings/bleio/ScanEntry.h | 44 ++++ shared-bindings/bleio/__init__.c | 20 +- shared-module/bleio/AdvertisementData.h | 76 ++++++ 14 files changed, 592 insertions(+), 229 deletions(-) delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_scan_entry.c create mode 100644 shared-bindings/bleio/AdvertisementData.c create mode 100644 shared-bindings/bleio/AdvertisementData.h create mode 100644 shared-bindings/bleio/ScanEntry.c create mode 100644 shared-bindings/bleio/ScanEntry.h create mode 100644 shared-module/bleio/AdvertisementData.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2de7f24bd..c5e0df02f 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -135,7 +135,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/ubluepy_delegate.c \ ubluepy/ubluepy_constants.c \ ubluepy/ubluepy_scanner.c \ - ubluepy/ubluepy_scan_entry.c \ ) SRC_COMMON_HAL += \ @@ -187,6 +186,8 @@ ifneq ($(SD), ) SRC_BINDINGS_ENUMS += \ bleio/Address.c \ bleio/AddressType.c \ + bleio/AdvertisementData.c \ + bleio/ScanEntry.c \ bleio/UUIDType.c endif diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 81d2a8ece..766660828 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -785,6 +785,18 @@ void ble_drv_scan_start(void) { } } +void ble_drv_scan_continue(void) { + SD_TEST_OR_ENABLE(); + +#if (BLUETOOTH_SD == 140) + uint32_t err_code; + if ((err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer)) != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Can not continue scanning. status: 0x" HEX2_FMT, (uint16_t)err_code)); + } +#endif +} + void ble_drv_scan_stop(void) { sd_ble_gap_scan_stop(); } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index d8b715467..ca9a38fdd 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -108,6 +108,8 @@ void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u void ble_drv_scan_start(void); +void ble_drv_scan_continue(void); + void ble_drv_scan_stop(void); void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler); diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index 0c02b22f2..034cc806c 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -34,7 +34,6 @@ extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_delegate_type; extern const mp_obj_type_t ubluepy_constants_type; extern const mp_obj_type_t ubluepy_scanner_type; -extern const mp_obj_type_t ubluepy_scan_entry_type; STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, @@ -46,7 +45,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { #endif #if MICROPY_PY_UBLUEPY_CENTRAL { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&ubluepy_scanner_type) }, - { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&ubluepy_scan_entry_type) }, #endif { MP_ROM_QSTR(MP_QSTR_DefaultDelegate), MP_ROM_PTR(&ubluepy_delegate_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index c5fd7b6f8..8fb9fadd0 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -78,7 +78,6 @@ extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_peripheral_type; extern const mp_obj_type_t ubluepy_scanner_type; -extern const mp_obj_type_t ubluepy_scan_entry_type; extern const mp_obj_type_t ubluepy_constants_type; extern const mp_obj_type_t ubluepy_constants_ad_types_type; @@ -153,15 +152,6 @@ typedef struct _ubluepy_scanner_obj_t { mp_obj_t adv_reports; } ubluepy_scanner_obj_t; -typedef struct _ubluepy_scan_entry_obj_t { - mp_obj_base_t base; - mp_obj_t addr; - uint8_t addr_type; - bool connectable; - int8_t rssi; - mp_obj_t data; -} ubluepy_scan_entry_obj_t; - typedef enum _ubluepy_prop_t { UBLUEPY_PROP_BROADCAST = 0x01, UBLUEPY_PROP_READ = 0x02, diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c index e53a6f068..b28bd3828 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ b/ports/nrf/modules/ubluepy/ubluepy_constants.c @@ -31,58 +31,11 @@ #include "modubluepy.h" -STATIC const mp_rom_map_elem_t ubluepy_constants_ad_types_locals_dict_table[] = { - // GAP AD Types - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_FLAGS), MP_ROM_INT(0x01) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x02) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x03) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x04) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x05) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x06) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x07) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SHORT_LOCAL_NAME), MP_ROM_INT(0x08) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_COMPLETE_LOCAL_NAME), MP_ROM_INT(0x09) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_TX_POWER_LEVEL), MP_ROM_INT(0x0A) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_CLASS_OF_DEVICE), MP_ROM_INT(0x0D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(0x0E) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(0x0F) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(0x10) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(0x11) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(0x12) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT), MP_ROM_INT(0x14) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT), MP_ROM_INT(0x15) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA), MP_ROM_INT(0x16) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(0x17) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_RANDOM_TARGET_ADDRESS), MP_ROM_INT(0x18) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_APPEARANCE), MP_ROM_INT(0x19) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_ADVERTISING_INTERVAL), MP_ROM_INT(0x1A) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(0x1B) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_LE_ROLE), MP_ROM_INT(0x1C) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(0x1D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(0x1E) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(0x20) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(0x21) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_URI), MP_ROM_INT(0x24) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_3D_INFORMATION_DATA), MP_ROM_INT(0x3D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(0xFF) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_ad_types_locals_dict, ubluepy_constants_ad_types_locals_dict_table); - -const mp_obj_type_t ubluepy_constants_ad_types_type = { - { &mp_type_type }, - .name = MP_QSTR_ad_types, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_ad_types_locals_dict -}; - STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { // GAP events { MP_ROM_QSTR(MP_QSTR_EVT_GAP_CONNECTED), MP_ROM_INT(16) }, { MP_ROM_QSTR(MP_QSTR_EVT_GAP_DISCONNECTED), MP_ROM_INT(17) }, { MP_ROM_QSTR(MP_QSTR_EVT_GATTS_WRITE), MP_ROM_INT(80) }, - { MP_ROM_QSTR(MP_QSTR_UUID_CCCD), MP_ROM_INT(0x2902) }, - - { MP_ROM_QSTR(MP_QSTR_ad_types), MP_ROM_PTR(&ubluepy_constants_ad_types_type) }, }; STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_locals_dict, ubluepy_constants_locals_dict_table); diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c deleted file mode 100644 index 773070b08..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 -#include "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" -#include "py/objarray.h" -#include "py/objtuple.h" -#include "py/qstr.h" - -#if MICROPY_PY_UBLUEPY_CENTRAL - -#include "ble_drv.h" - -STATIC void ubluepy_scan_entry_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_scan_entry_obj_t * self = (ubluepy_scan_entry_obj_t *)o; - (void)self; - mp_printf(print, "ScanEntry"); -} - -/// \method addr() -/// Return address as text string. -/// -STATIC mp_obj_t scan_entry_get_addr(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return self->addr; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_addr_obj, scan_entry_get_addr); - -/// \method addr_type() -/// Return address type value. -/// -STATIC mp_obj_t scan_entry_get_addr_type(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->addr_type); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_addr_type_obj, scan_entry_get_addr_type); - -/// \method rssi() -/// Return RSSI value. -/// -STATIC mp_obj_t scan_entry_get_rssi(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->rssi); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_rssi_obj, scan_entry_get_rssi); - -/// \method getScanData() -/// Return list of the scan data tupples (ad_type, description, value) -/// -STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t * self = MP_OBJ_TO_PTR(self_in); - - mp_obj_t retval_list = mp_obj_new_list(0, NULL); - - // TODO: check if self->data is set - mp_obj_array_t * data = MP_OBJ_TO_PTR(self->data); - - uint16_t byte_index = 0; - - while (byte_index < data->len) { - mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); - - uint8_t adv_item_len = ((uint8_t * )data->items)[byte_index]; - uint8_t adv_item_type = ((uint8_t * )data->items)[byte_index + 1]; - - mp_obj_t description = mp_const_none; - - mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict); - mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table); - - uint16_t num_of_elements = constant_map->used; - - for (uint16_t i = 0; i < num_of_elements; i++) { - mp_map_elem_t element = (mp_map_elem_t)*ad_types_table; - ad_types_table++; - uint16_t element_value = mp_obj_get_int(element.value); - - if (adv_item_type == element_value) { - qstr key_qstr = MP_OBJ_QSTR_VALUE(element.key); - const char * text = qstr_str(key_qstr); - size_t len = qstr_len(key_qstr); - - vstr_t vstr; - vstr_init(&vstr, len); - vstr_printf(&vstr, "%s", text); - description = mp_obj_new_str(vstr.buf, vstr.len); - vstr_clear(&vstr); - } - } - - t->items[0] = MP_OBJ_NEW_SMALL_INT(adv_item_type); - t->items[1] = description; - t->items[2] = mp_obj_new_bytearray(adv_item_len - 1, - &((uint8_t * )data->items)[byte_index + 2]); - mp_obj_list_append(retval_list, MP_OBJ_FROM_PTR(t)); - - byte_index += adv_item_len + 1; - } - - return retval_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_scan_entry_get_scan_data_obj, scan_entry_get_scan_data); - -STATIC const mp_rom_map_elem_t ubluepy_scan_entry_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_addr), MP_ROM_PTR(&bluepy_scan_entry_get_addr_obj) }, - { MP_ROM_QSTR(MP_QSTR_addr_type), MP_ROM_PTR(&bluepy_scan_entry_get_addr_type_obj) }, - { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bluepy_scan_entry_get_rssi_obj) }, - { MP_ROM_QSTR(MP_QSTR_getScanData), MP_ROM_PTR(&ubluepy_scan_entry_get_scan_data_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_scan_entry_locals_dict, ubluepy_scan_entry_locals_dict_table); - -const mp_obj_type_t ubluepy_scan_entry_type = { - { &mp_type_type }, - .name = MP_QSTR_ScanEntry, - .print = ubluepy_scan_entry_print, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scan_entry_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c index 1cde3d551..9d15037a5 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ b/ports/nrf/modules/ubluepy/ubluepy_scanner.c @@ -33,31 +33,25 @@ #if MICROPY_PY_UBLUEPY_CENTRAL +#include "shared-bindings/bleio/ScanEntry.h" #include "ble_drv.h" STATIC void adv_event_handler(mp_obj_t self_in, uint16_t event_id, ble_drv_adv_data_t * data) { ubluepy_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); - ubluepy_scan_entry_obj_t * item = m_new_obj(ubluepy_scan_entry_obj_t); - item->base.type = &ubluepy_scan_entry_type; + // TODO: Don't add new entry for each item, group by address and update + bleio_scanentry_obj_t *item = m_new_obj(bleio_scanentry_obj_t); + item->base.type = &bleio_scanentry_type; - vstr_t vstr; - vstr_init(&vstr, 17); + item->rssi = data->rssi; + item->data = mp_obj_new_bytearray(data->data_len, data->p_data); - vstr_printf(&vstr, ""HEX2_FMT":"HEX2_FMT":"HEX2_FMT":" \ - HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", - data->p_peer_addr[5], data->p_peer_addr[4], data->p_peer_addr[3], - data->p_peer_addr[2], data->p_peer_addr[1], data->p_peer_addr[0]); - - item->addr = mp_obj_new_str(vstr.buf, vstr.len); - - vstr_clear(&vstr); - - item->addr_type = data->addr_type; - item->rssi = data->rssi; - item->data = mp_obj_new_bytearray(data->data_len, data->p_data); + item->address.type = data->addr_type; + memcpy(item->address.value, data->p_peer_addr, BLEIO_ADDRESS_BYTES); mp_obj_list_append(self->adv_reports, item); + + ble_drv_scan_continue(); } STATIC void ubluepy_scanner_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c new file mode 100644 index 000000000..545dd5c51 --- /dev/null +++ b/shared-bindings/bleio/AdvertisementData.c @@ -0,0 +1,92 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/obj.h" +#include "shared-module/bleio/AdvertisementData.h" + +//| .. currentmodule:: bleio +//| +//| :class:`AdvertisementData` -- data used during BLE advertising +//| ============================================================== +//| +//| Represents the data to be broadcast during BLE advertising. +//| + +// TODO: Implement constructor and methods + +STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = { + // Static variables + { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) }, + { MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) }, + { MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) }, + { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) }, + { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) }, + { MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) }, + { MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) }, + { MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) }, + { MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) }, + { MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) }, + { MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) }, + { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) }, + { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) }, + { MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) }, + { MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) }, + { MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) }, + { MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) }, + { MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) }, + { MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) }, + { MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) }, + { MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) }, + { MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) }, + { MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table); + +const mp_obj_type_t bleio_advertisementdata_type = { + { &mp_type_type }, + .name = MP_QSTR_AdvertisementData, + .locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict +}; diff --git a/shared-bindings/bleio/AdvertisementData.h b/shared-bindings/bleio/AdvertisementData.h new file mode 100644 index 000000000..05b5a2c8d --- /dev/null +++ b/shared-bindings/bleio/AdvertisementData.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H + +#include "py/obj.h" + +extern const mp_obj_type_t bleio_advertisementdata_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c new file mode 100644 index 000000000..f41665581 --- /dev/null +++ b/shared-bindings/bleio/ScanEntry.c @@ -0,0 +1,307 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/objtuple.h" +#include "shared-bindings/bleio/Address.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/bleio/ScanEntry.h" + +//| .. currentmodule:: bleio +//| +//| :class:`ScanEntry` -- BLE scan response entry +//| ========================================================= +//| +//| Encapsulates information about a device that was received as a +//| response to a BLE scan request. +//| + +//| .. attribute:: address +//| +//| The address of the device. (read-only) +//| This attribute is of type `bleio:Address`. +//| + +//| .. attribute:: manufacturer_specific_data +//| +//| The manufacturer-specific data present in the advertisement packet. (read-only) +//| + +//| .. attribute:: name +//| +//| The name of the device. (read-only) +//| This attribute might be `None` if the data was missing from the advertisement packet. +//| + +//| .. attribute:: raw_data +//| +//| All the advertisement data present in the packet. (read-only) +//| + +//| .. attribute:: rssi +//| +//| The signal strength of the device at the time of the scan. (read-only) +//| + +//| .. attribute:: service_uuids +//| +//| The address of the device. (read-only) +//| This attribute is a list of `bleio:UUID`. +//| This attribute might be empty or incomplete, depending on the advertisement packet. +//| Currently only 16-bit UUIDS are listed. +//| + +//| .. attribute:: tx_power_level +//| +//| The transmit power level of the device. (read-only) +//| This attribute might be `None` if the data was missing from the advertisement packet. +//| +static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) { + uint16_t i = 0; + while (i < data_in->len) { + const uint8_t item_len = ((uint8_t*)data_in->items)[i]; + const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1]; + if (item_type != type) { + i += (item_len + 1); + continue; + } + + *data_out = &((uint8_t*)data_in->items)[i + 2]; + + return item_len; + } + + return 0; +} + +STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in); + +STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in; + mp_printf(print, "ScanEntry(address: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", + self->address.value[5], self->address.value[4], self->address.value[3], + self->address.value[1], self->address.value[1], self->address.value[0]); + + const mp_obj_t name_obj = scanentry_get_name(self_in); + if (name_obj != mp_const_none) { + mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj); + mp_printf(print, " name: %s", str->data); + } + + mp_print_str(print, ")"); +} + +STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj); + bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); + + address->type = self->address.type; + memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES); + + return obj; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address); + +const mp_obj_property_t bleio_scanentry_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *manuf_data; + + const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data); + if (manuf_data_len == 0) { + return mp_const_none; + } + + return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data); + +const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *name; + + // Try for Complete but settle for Shortened + uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name); + if (name_len == 0) { + name_len = find_data_item(data, AdShortenedLocalName, &name); + } + + if (name_len == 0) { + return mp_const_none; + } + + return mp_obj_new_str((const char*)name, name_len - 1, false); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name); + +const mp_obj_property_t bleio_scanentry_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_obj_t entries = mp_obj_new_list(0, NULL); + + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + + uint16_t i = 0; + while (i < data->len) { + mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + + const uint8_t item_len = ((uint8_t*)data->items)[i]; + const uint8_t item_type = ((uint8_t*)data->items)[i + 1]; + + entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type); + entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]); + mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry)); + + i += (item_len + 1); + } + + return entries; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data); + +const mp_obj_property_t bleio_scanentry_raw_data_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanentry_get_raw_data_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->rssi); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_rssi_obj, scanentry_get_rssi); + +const mp_obj_property_t bleio_scanentry_rssi_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_rssi_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *uuids; + + // Try for Complete but settle for Incomplete + uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids); + if (uuids_len == 0) { + uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids); + } + + mp_obj_t entries = mp_obj_new_list(0, NULL); + for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) { + const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8)); + const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_int); + + mp_obj_list_append(entries, uuid_obj); + } + + // TODO: 32-bit UUIDs + // TODO: 128-bit UUIDs + + return entries; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids); + +const mp_obj_property_t bleio_scanentry_service_uuids_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *tx_power; + + const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power); + if (tx_power_len == 0) { + return mp_const_none; + } + + return mp_obj_new_int((int8_t)(*tx_power)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level); + +const mp_obj_property_t bleio_scanentry_tx_power_level_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) }, + { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) }, + { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table); + +const mp_obj_type_t bleio_scanentry_type = { + { &mp_type_type }, + .name = MP_QSTR_ScanEntry, + .print = bleio_scanentry_print, + .locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict +}; diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h new file mode 100644 index 000000000..4a201124e --- /dev/null +++ b/shared-bindings/bleio/ScanEntry.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H + +#include "shared-module/bleio/Address.h" +#include "py/objtype.h" + +typedef struct { + mp_obj_base_t base; + bleio_address_obj_t address; + bool connectable; + int8_t rssi; + mp_obj_t data; +} bleio_scanentry_obj_t; + +extern const mp_obj_type_t bleio_scanentry_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 570b71798..315b2c32c 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -29,7 +29,9 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/AddressType.h" +#include "shared-bindings/bleio/AdvertisementData.h" #include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/UUIDType.h" @@ -49,8 +51,10 @@ //| //| Address //| AddressType +//| AdvertisementData //| Adapter //| Descriptor +//| ScanEntry //| UUID //| UUIDType //| @@ -62,17 +66,19 @@ //| STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, - { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, - { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, - { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, - { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, + { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties - { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, // Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, + { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, + { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h new file mode 100644 index 000000000..0ebc48ea7 --- /dev/null +++ b/shared-module/bleio/AdvertisementData.h @@ -0,0 +1,76 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H + +// Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile +enum { + AdFlags = 0x01, + AdIncompleteListOf16BitServiceClassUUIDs = 0x02, + AdCompleteListOf16BitServiceClassUUIDs = 0x03, + AdIncompleteListOf32BitServiceClassUUIDs = 0x04, + AdCompleteListOf32BitServiceClassUUIDs = 0x05, + AdIncompleteListOf128BitServiceClassUUIDs = 0x06, + AdCompleteListOf128BitServiceClassUUIDs = 0x07, + AdShortenedLocalName = 0x08, + AdCompleteLocalName = 0x09, + AdTxPowerLevel = 0x0A, + AdClassOfDevice = 0x0D, + AdSimplePairingHashC = 0x0E, + AdSimplePairingRandomizerR = 0x0F, + AdSecurityManagerTKValue = 0x10, + AdSecurityManagerOOBFlags = 0x11, + AdSlaveConnectionIntervalRange = 0x12, + AdListOf16BitServiceSolicitationUUIDs = 0x14, + AdListOf128BitServiceSolicitationUUIDs = 0x15, + AdServiceData = 0x16, + AdPublicTargetAddress = 0x17, + AdRandomTargetAddress = 0x18, + AdAppearance = 0x19, + AdAdvertisingInterval = 0x1A, + AdLEBluetoothDeviceAddress = 0x1B, + AdLERole = 0x1C, + AdSimplePairingHashC256 = 0x1D, + AdSimplePairingRandomizerR256 = 0x1E, + AdListOf32BitServiceSolicitationUUIDs = 0x1F, + AdServiceData32BitUUID = 0x20, + AdServiceData128BitUUID = 0x21, + AdLESecureConnectionsConfirmationValue = 0x22, + AdLESecureConnectionsRandomValue = 0x23, + AdURI = 0x24, + AdIndoorPositioning = 0x25, + AdTransportDiscoveryData = 0x26, + AdLESupportedFeatures = 0x27, + AdChannelMapUpdateIndication = 0x28, + AdPBADV = 0x29, + AdMeshMessage = 0x2A, + AdMeshBeacon = 0x2B, + Ad3DInformationData = 0x3D, + AdManufacturerSpecificData = 0xFF, +}; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H -- cgit v1.2.3 From 1c6bf9a15061d64ea097a024d73ad0a6da8f8e2b Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 18 Jul 2018 10:22:11 +0200 Subject: bleio: Move the Scanner class to a shared module --- ports/nrf/Makefile | 2 +- ports/nrf/common-hal/bleio/Scanner.c | 59 ++++++++++ ports/nrf/drivers/bluetooth/ble_drv.c | 19 ++-- ports/nrf/drivers/bluetooth/ble_drv.h | 8 +- ports/nrf/modules/ubluepy/modubluepy.c | 4 - ports/nrf/modules/ubluepy/modubluepy.h | 6 -- ports/nrf/modules/ubluepy/ubluepy_scanner.c | 118 -------------------- shared-bindings/bleio/ScanEntry.c | 4 +- shared-bindings/bleio/Scanner.c | 161 ++++++++++++++++++++++++++++ shared-bindings/bleio/Scanner.h | 38 +++++++ shared-bindings/bleio/__init__.c | 3 + shared-module/bleio/Scanner.h | 39 +++++++ 12 files changed, 317 insertions(+), 144 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Scanner.c delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_scanner.c create mode 100644 shared-bindings/bleio/Scanner.c create mode 100644 shared-bindings/bleio/Scanner.h create mode 100644 shared-module/bleio/Scanner.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index c5e0df02f..3873f2cbc 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -134,7 +134,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/ubluepy_characteristic.c \ ubluepy/ubluepy_delegate.c \ ubluepy/ubluepy_constants.c \ - ubluepy/ubluepy_scanner.c \ ) SRC_COMMON_HAL += \ @@ -167,6 +166,7 @@ SRC_COMMON_HAL += \ bleio/__init__.c \ bleio/Adapter.c \ bleio/Descriptor.c \ + bleio/Scanner.c \ bleio/UUID.c endif diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c new file mode 100644 index 000000000..ed1987144 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 + +#include "ble_drv.h" +#include "py/mphal.h" +#include "shared-bindings/bleio/Scanner.h" +#include "shared-bindings/bleio/ScanEntry.h" + +STATIC void adv_event_handler(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data) { + // TODO: Don't add new entry for each item, group by address and update + bleio_scanentry_obj_t *item = m_new_obj(bleio_scanentry_obj_t); + item->base.type = &bleio_scanentry_type; + + item->rssi = data->rssi; + item->data = mp_obj_new_bytearray(data->data_len, data->p_data); + + item->address.type = data->addr_type; + memcpy(item->address.value, data->p_peer_addr, BLEIO_ADDRESS_BYTES); + + mp_obj_list_append(self->adv_reports, item); + + ble_drv_scan_continue(); +} + +void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) { + ble_drv_adv_report_handler_set(self, adv_event_handler); + + ble_drv_scan_start(self->interval, self->window); + + mp_hal_delay_ms(timeout); + + ble_drv_scan_stop(); +} diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 766660828..1d67842ef 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -94,7 +94,7 @@ static volatile ble_drv_disc_add_service_callback_t disc_add_service_handler; static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler; static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; -static mp_obj_t mp_adv_observer; +static bleio_scanner_obj_t *mp_adv_observer; static mp_obj_t mp_gattc_observer; static mp_obj_t mp_gattc_disc_service_observer; static mp_obj_t mp_gattc_disc_char_observer; @@ -707,8 +707,8 @@ void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t gattc_event_handler = evt_handler; } -void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler) { - mp_adv_observer = obj; +void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler) { + mp_adv_observer = self; adv_event_handler = evt_handler; } @@ -760,15 +760,15 @@ void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u ; } } -void ble_drv_scan_start(void) { +void ble_drv_scan_start(uint16_t interval, uint16_t window) { SD_TEST_OR_ENABLE(); ble_gap_scan_params_t scan_params; memset(&scan_params, 0, sizeof(ble_gap_scan_params_t)); scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); + scan_params.interval = MSEC_TO_UNITS(interval, UNIT_0_625_MS); + scan_params.window = MSEC_TO_UNITS(window, UNIT_0_625_MS); #if (BLUETOOTH_SD == 140) scan_params.scan_phys = BLE_GAP_PHY_1MBPS; #endif @@ -1003,10 +1003,9 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) { #endif }; - // TODO: Fix unsafe callback to possible undefined callback... - adv_event_handler(mp_adv_observer, - p_ble_evt->header.evt_id, - &adv_data); + if (adv_event_handler != NULL) { + adv_event_handler(mp_adv_observer, &adv_data); + } break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index ca9a38fdd..d344e2690 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -32,6 +32,8 @@ #include #include +#include "shared-module/bleio/Scanner.h" + #include "modubluepy.h" typedef struct { @@ -67,7 +69,7 @@ typedef struct { typedef void (*ble_drv_gap_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gatts_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gattc_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_adv_evt_callback_t)(mp_obj_t self, uint16_t event_id, ble_drv_adv_data_t * data); +typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data); typedef void (*ble_drv_disc_add_service_callback_t)(mp_obj_t self, ble_drv_service_data_t * p_service_data); typedef void (*ble_drv_disc_add_char_callback_t)(mp_obj_t self, ble_drv_char_data_t * p_desc_data); typedef void (*ble_drv_gattc_char_data_callback_t)(mp_obj_t self, uint16_t length, uint8_t * p_data); @@ -106,13 +108,13 @@ void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response); -void ble_drv_scan_start(void); +void ble_drv_scan_start(uint16_t interval, uint16_t window); void ble_drv_scan_continue(void); void ble_drv_scan_stop(void); -void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler); +void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler); void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type); diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index 034cc806c..e817983fa 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -33,7 +33,6 @@ extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_delegate_type; extern const mp_obj_type_t ubluepy_constants_type; -extern const mp_obj_type_t ubluepy_scanner_type; STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, @@ -42,9 +41,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { #endif #if 0 // MICROPY_PY_UBLUEPY_CENTRAL { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&ubluepy_central_type) }, -#endif -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&ubluepy_scanner_type) }, #endif { MP_ROM_QSTR(MP_QSTR_DefaultDelegate), MP_ROM_PTR(&ubluepy_delegate_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index 8fb9fadd0..f51cc9e87 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -77,7 +77,6 @@ p.advertise(device_name="micr", services=[s]) extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_peripheral_type; -extern const mp_obj_type_t ubluepy_scanner_type; extern const mp_obj_type_t ubluepy_constants_type; extern const mp_obj_type_t ubluepy_constants_ad_types_type; @@ -147,11 +146,6 @@ typedef struct _ubluepy_advertise_data_t { bool connectable; } ubluepy_advertise_data_t; -typedef struct _ubluepy_scanner_obj_t { - mp_obj_base_t base; - mp_obj_t adv_reports; -} ubluepy_scanner_obj_t; - typedef enum _ubluepy_prop_t { UBLUEPY_PROP_BROADCAST = 0x01, UBLUEPY_PROP_READ = 0x02, diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c deleted file mode 100644 index 9d15037a5..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 -#include "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" -#include "py/mphal.h" - -#if MICROPY_PY_UBLUEPY_CENTRAL - -#include "shared-bindings/bleio/ScanEntry.h" -#include "ble_drv.h" - -STATIC void adv_event_handler(mp_obj_t self_in, uint16_t event_id, ble_drv_adv_data_t * data) { - ubluepy_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // TODO: Don't add new entry for each item, group by address and update - bleio_scanentry_obj_t *item = m_new_obj(bleio_scanentry_obj_t); - item->base.type = &bleio_scanentry_type; - - item->rssi = data->rssi; - item->data = mp_obj_new_bytearray(data->data_len, data->p_data); - - item->address.type = data->addr_type; - memcpy(item->address.value, data->p_peer_addr, BLEIO_ADDRESS_BYTES); - - mp_obj_list_append(self->adv_reports, item); - - ble_drv_scan_continue(); -} - -STATIC void ubluepy_scanner_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_scanner_obj_t * self = (ubluepy_scanner_obj_t *)o; - (void)self; - mp_printf(print, "Scanner"); -} - -STATIC mp_obj_t ubluepy_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - static const mp_arg_t allowed_args[] = { - - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_scanner_obj_t * s = m_new_obj(ubluepy_scanner_obj_t); - s->base.type = type; - - return MP_OBJ_FROM_PTR(s); -} - -/// \method scan(timeout) -/// Scan for devices. Timeout is in milliseconds and will set the duration -/// of the scanning. -/// -STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) { - ubluepy_scanner_obj_t * self = MP_OBJ_TO_PTR(self_in); - mp_int_t timeout = mp_obj_get_int(timeout_in); - - self->adv_reports = mp_obj_new_list(0, NULL); - - ble_drv_adv_report_handler_set(MP_OBJ_FROM_PTR(self), adv_event_handler); - - // start - ble_drv_scan_start(); - - // sleep - mp_hal_delay_ms(timeout); - - // stop - ble_drv_scan_stop(); - - return self->adv_reports; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_scanner_scan_obj, scanner_scan); - -STATIC const mp_rom_map_elem_t ubluepy_scanner_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&ubluepy_scanner_scan_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_scanner_locals_dict, ubluepy_scanner_locals_dict_table); - - -const mp_obj_type_t ubluepy_scanner_type = { - { &mp_type_type }, - .name = MP_QSTR_Scanner, - .print = ubluepy_scanner_print, - .make_new = ubluepy_scanner_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scanner_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c index f41665581..e38a08909 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/bleio/ScanEntry.c @@ -48,7 +48,7 @@ //| .. attribute:: address //| //| The address of the device. (read-only) -//| This attribute is of type `bleio:Address`. +//| This attribute is of type `bleio.Address`. //| //| .. attribute:: manufacturer_specific_data @@ -75,7 +75,7 @@ //| .. attribute:: service_uuids //| //| The address of the device. (read-only) -//| This attribute is a list of `bleio:UUID`. +//| This attribute is a list of `bleio.UUID`. //| This attribute might be empty or incomplete, depending on the advertisement packet. //| Currently only 16-bit UUIDS are listed. //| diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c new file mode 100644 index 000000000..00e29d9d5 --- /dev/null +++ b/shared-bindings/bleio/Scanner.c @@ -0,0 +1,161 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Scanner.h" + +#define DEFAULT_INTERVAL 100 +#define DEFAULT_WINDOW 100 + +//| .. currentmodule:: bleio +//| +//| :class:`Scanner` -- scan for nearby BLE devices +//| ========================================================= +//| +//| Allows scanning for nearby BLE devices. +//| +//| Usage:: +//| +//| import bleio +//| scanner = bleio.Scanner() +//| entries = scanner.scan(2500) +//| print(entries) +//| + +//| .. class:: Scanner() +//| +//| Create a new Scanner object. +//| + +//| .. attribute:: interval +//| +//| The interval (in ms) between the start of two consecutive scan windows. +//| Allowed values are between 10ms and 10.24 sec. +//| + +//| .. attribute:: window +//| +//| The duration (in ms) in which a single BLE channel is scanned. +//| Allowed values are between 10ms and 10.24 sec. +//| + +//| .. method:: scan(timeout) +//| +//| Performs a BLE scan lasting :py:data:`timeout` ms. +//| +//| :returns: advertising packets found +//| :rtype: list of :py:class:`bleio.ScanEntry` +//| +STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window); +} + +STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t); + self->base.type = type; + + self->interval = DEFAULT_INTERVAL; + self->window = DEFAULT_WINDOW; + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_scanner_get_interval(mp_obj_t self_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->interval); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_interval_obj, bleio_scanner_get_interval); + +static mp_obj_t bleio_scanner_set_interval(mp_obj_t self_in, mp_obj_t value) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->interval = mp_obj_get_int(value); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_interval_obj, bleio_scanner_set_interval); + +const mp_obj_property_t bleio_scanner_interval_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanner_get_interval_obj, + (mp_obj_t)&bleio_scanner_set_interval_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + const mp_int_t timeout = mp_obj_get_int(timeout_in); + + self->adv_reports = mp_obj_new_list(0, NULL); + + common_hal_bleio_scanner_scan(self, timeout); + + return self->adv_reports; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_scan_obj, scanner_scan); + +STATIC mp_obj_t bleio_scanner_get_window(mp_obj_t self_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->window); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_window_obj, bleio_scanner_get_window); + +static mp_obj_t bleio_scanner_set_window(mp_obj_t self_in, mp_obj_t value) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->window = mp_obj_get_int(value); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_window_obj, bleio_scanner_set_window); + +const mp_obj_property_t bleio_scanner_window_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanner_get_window_obj, + (mp_obj_t)&bleio_scanner_set_window_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_interval), MP_ROM_PTR(&bleio_scanner_interval_obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) }, + { MP_ROM_QSTR(MP_QSTR_window), MP_ROM_PTR(&bleio_scanner_window_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table); + +const mp_obj_type_t bleio_scanner_type = { + { &mp_type_type }, + .name = MP_QSTR_Scanner, + .print = bleio_scanner_print, + .make_new = bleio_scanner_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict +}; diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h new file mode 100644 index 000000000..03db5cd8b --- /dev/null +++ b/shared-bindings/bleio/Scanner.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H + +#include "py/objtype.h" +#include "shared-module/bleio/Scanner.h" + +extern const mp_obj_type_t bleio_scanner_type; + +extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 315b2c32c..4ad858ac9 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -32,6 +32,7 @@ #include "shared-bindings/bleio/AdvertisementData.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/UUIDType.h" @@ -55,6 +56,7 @@ //| Adapter //| Descriptor //| ScanEntry +//| Scanner //| UUID //| UUIDType //| @@ -71,6 +73,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, + { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties diff --git a/shared-module/bleio/Scanner.h b/shared-module/bleio/Scanner.h new file mode 100644 index 000000000..f1159adfe --- /dev/null +++ b/shared-module/bleio/Scanner.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t adv_reports; + uint16_t interval; + uint16_t window; +} bleio_scanner_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H -- cgit v1.2.3 From 61bf4a16a7b1c4484a13121c2b64e5fd37d2ab01 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 18 Jul 2018 10:28:54 +0200 Subject: nrf: Remove unused ubluepy classes --- ports/nrf/Makefile | 2 - ports/nrf/modules/ubluepy/modubluepy.c | 8 --- ports/nrf/modules/ubluepy/modubluepy.h | 6 -- ports/nrf/modules/ubluepy/ubluepy_constants.c | 49 --------------- ports/nrf/modules/ubluepy/ubluepy_delegate.c | 89 --------------------------- 5 files changed, 154 deletions(-) delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_constants.c delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_delegate.c diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 3873f2cbc..8a4454a0a 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -132,8 +132,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/ubluepy_peripheral.c \ ubluepy/ubluepy_service.c \ ubluepy/ubluepy_characteristic.c \ - ubluepy/ubluepy_delegate.c \ - ubluepy/ubluepy_constants.c \ ) SRC_COMMON_HAL += \ diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index e817983fa..1470f4a37 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -31,24 +31,16 @@ extern const mp_obj_type_t ubluepy_peripheral_type; extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; -extern const mp_obj_type_t ubluepy_delegate_type; -extern const mp_obj_type_t ubluepy_constants_type; STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, #if MICROPY_PY_UBLUEPY_PERIPHERAL { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) }, #endif -#if 0 // MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&ubluepy_central_type) }, -#endif - { MP_ROM_QSTR(MP_QSTR_DefaultDelegate), MP_ROM_PTR(&ubluepy_delegate_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&ubluepy_characteristic_type) }, - { MP_ROM_QSTR(MP_QSTR_constants), MP_ROM_PTR(&ubluepy_constants_type) }, }; - STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table); const mp_obj_module_t mp_module_ubluepy = { diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index f51cc9e87..5d80e3536 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -77,8 +77,6 @@ p.advertise(device_name="micr", services=[s]) extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_peripheral_type; -extern const mp_obj_type_t ubluepy_constants_type; -extern const mp_obj_type_t ubluepy_constants_ad_types_type; typedef enum { UBLUEPY_SERVICE_PRIMARY = 1, @@ -132,10 +130,6 @@ typedef struct _ubluepy_characteristic_obj_t { mp_obj_t value_data; } ubluepy_characteristic_obj_t; -typedef struct _ubluepy_delegate_obj_t { - mp_obj_base_t base; -} ubluepy_delegate_obj_t; - typedef struct _ubluepy_advertise_data_t { uint8_t * p_device_name; uint8_t device_name_len; diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c deleted file mode 100644 index b28bd3828..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" - -STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { - // GAP events - { MP_ROM_QSTR(MP_QSTR_EVT_GAP_CONNECTED), MP_ROM_INT(16) }, - { MP_ROM_QSTR(MP_QSTR_EVT_GAP_DISCONNECTED), MP_ROM_INT(17) }, - { MP_ROM_QSTR(MP_QSTR_EVT_GATTS_WRITE), MP_ROM_INT(80) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_locals_dict, ubluepy_constants_locals_dict_table); - -const mp_obj_type_t ubluepy_constants_type = { - { &mp_type_type }, - .name = MP_QSTR_constants, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_delegate.c b/ports/nrf/modules/ubluepy/ubluepy_delegate.c deleted file mode 100644 index 07bb7f492..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_delegate.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" - -STATIC void ubluepy_delegate_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_delegate_obj_t * self = (ubluepy_delegate_obj_t *)o; - (void)self; - mp_printf(print, "DefaultDelegate()"); -} - -STATIC mp_obj_t ubluepy_delegate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - ubluepy_delegate_obj_t *s = m_new_obj(ubluepy_delegate_obj_t); - s->base.type = type; - - return MP_OBJ_FROM_PTR(s); -} - -/// \method handleConnection() -/// Handle connection events. -/// -STATIC mp_obj_t delegate_handle_conn(mp_obj_t self_in) { - ubluepy_delegate_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_delegate_handle_conn_obj, delegate_handle_conn); - -/// \method handleNotification() -/// Handle notification events. -/// -STATIC mp_obj_t delegate_handle_notif(mp_obj_t self_in) { - ubluepy_delegate_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_delegate_handle_notif_obj, delegate_handle_notif); - -STATIC const mp_rom_map_elem_t ubluepy_delegate_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_handleConnection), MP_ROM_PTR(&ubluepy_delegate_handle_conn_obj) }, - { MP_ROM_QSTR(MP_QSTR_handleNotification), MP_ROM_PTR(&ubluepy_delegate_handle_notif_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_handleDiscovery), MP_ROM_PTR(&ubluepy_delegate_handle_disc_obj) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_delegate_locals_dict, ubluepy_delegate_locals_dict_table); - -const mp_obj_type_t ubluepy_delegate_type = { - { &mp_type_type }, - .name = MP_QSTR_DefaultDelegate, - .print = ubluepy_delegate_print, - .make_new = ubluepy_delegate_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_delegate_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL -- cgit v1.2.3 From fb422ccf5e4dcf644a4c99fe4843af2838a23907 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 18 Jul 2018 10:47:58 +0200 Subject: bleio: Remove SAMD mention in include guard Damn copy-paste! --- shared-module/bleio/Address.h | 6 +++--- shared-module/bleio/AdvertisementData.h | 6 +++--- shared-module/bleio/Scanner.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/shared-module/bleio/Address.h b/shared-module/bleio/Address.h index a520b8dd6..f0998c163 100644 --- a/shared-module/bleio/Address.h +++ b/shared-module/bleio/Address.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H #include "shared-bindings/bleio/AddressType.h" @@ -37,4 +37,4 @@ typedef struct { uint8_t value[BLEIO_ADDRESS_BYTES]; } bleio_address_obj_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADDRESS_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h index 0ebc48ea7..2a9addf57 100644 --- a/shared-module/bleio/AdvertisementData.h +++ b/shared-module/bleio/AdvertisementData.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H // Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile enum { @@ -73,4 +73,4 @@ enum { AdManufacturerSpecificData = 0xFF, }; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H diff --git a/shared-module/bleio/Scanner.h b/shared-module/bleio/Scanner.h index f1159adfe..76f5e5866 100644 --- a/shared-module/bleio/Scanner.h +++ b/shared-module/bleio/Scanner.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H #include "py/obj.h" @@ -36,4 +36,4 @@ typedef struct { uint16_t window; } bleio_scanner_obj_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BLEIO_SCANNER_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H -- cgit v1.2.3 From cc782492269f2311995269507ff1411d3bbb8a2f Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 18 Jul 2018 23:47:06 +0200 Subject: nrf: Move the Characteristic class from ubluepy to the shared bleio module --- ports/nrf/Makefile | 2 +- ports/nrf/common-hal/bleio/Characteristic.c | 53 ++++ ports/nrf/common-hal/bleio/UUID.h | 1 - ports/nrf/drivers/bluetooth/ble_drv.c | 151 +++++----- ports/nrf/drivers/bluetooth/ble_drv.h | 22 +- ports/nrf/modules/ubluepy/modubluepy.c | 2 - ports/nrf/modules/ubluepy/modubluepy.h | 15 - ports/nrf/modules/ubluepy/ubluepy_characteristic.c | 224 -------------- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 18 +- ports/nrf/modules/ubluepy/ubluepy_service.c | 11 +- shared-bindings/bleio/Characteristic.c | 330 +++++++++++++++++++++ shared-bindings/bleio/Characteristic.h | 37 +++ shared-bindings/bleio/__init__.c | 3 + shared-module/bleio/Characteristic.h | 52 ++++ 14 files changed, 578 insertions(+), 343 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Characteristic.c delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_characteristic.c create mode 100644 shared-bindings/bleio/Characteristic.c create mode 100644 shared-bindings/bleio/Characteristic.h create mode 100644 shared-module/bleio/Characteristic.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8a4454a0a..6ed2d3054 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -131,7 +131,6 @@ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/modubluepy.c \ ubluepy/ubluepy_peripheral.c \ ubluepy/ubluepy_service.c \ - ubluepy/ubluepy_characteristic.c \ ) SRC_COMMON_HAL += \ @@ -163,6 +162,7 @@ ifneq ($(SD), ) SRC_COMMON_HAL += \ bleio/__init__.c \ bleio/Adapter.c \ + bleio/Characteristic.c \ bleio/Descriptor.c \ bleio/Scanner.c \ bleio/UUID.c diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c new file mode 100644 index 000000000..3087b6707 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "ble_drv.h" +#include "shared-module/bleio/Characteristic.h" + +void data_callback(bleio_characteristic_obj_t *self, uint16_t length, uint8_t *data) { + self->value_data = mp_obj_new_bytearray(length, data); +} + +void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { + ble_drv_attr_c_read(self, data_callback); +} + +void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(self->service); + ubluepy_role_type_t role = service->p_periph->role; + + if (role == UBLUEPY_ROLE_PERIPHERAL) { + // TODO: Add indications + if (self->props.notify) { + ble_drv_attr_s_notify(self, bufinfo); + } else { + ble_drv_attr_s_write(self, bufinfo); + } + } else { + ble_drv_attr_c_write(self, bufinfo); + } + +} diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h index b919fec28..cb0fddcfd 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -28,7 +28,6 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H -#include "py/obj.h" #include "shared-bindings/bleio/UUIDType.h" typedef struct { diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 1d67842ef..6240a18e4 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -98,7 +98,7 @@ static bleio_scanner_obj_t *mp_adv_observer; static mp_obj_t mp_gattc_observer; static mp_obj_t mp_gattc_disc_service_observer; static mp_obj_t mp_gattc_disc_char_observer; -static mp_obj_t mp_gattc_char_data_observer; +static bleio_characteristic_obj_t *mp_gattc_char_data_observer; #if (BLUETOOTH_SD == 140) static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; @@ -270,38 +270,26 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) { bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) { SD_TEST_OR_ENABLE(); - if (p_service_obj->p_uuid->type > BLE_UUID_TYPE_BLE) { + ble_uuid_t uuid; + uuid.type = BLE_UUID_TYPE_BLE; + uuid.uuid = p_service_obj->p_uuid->value[0] | (p_service_obj->p_uuid->value[1] << 8); - ble_uuid_t uuid; + if (p_service_obj->p_uuid->type == UUID_TYPE_128BIT) { uuid.type = p_service_obj->p_uuid->uuid_vs_idx; - uuid.uuid = p_service_obj->p_uuid->value[0]; - uuid.uuid += p_service_obj->p_uuid->value[1] << 8; - - if (sd_ble_gatts_service_add(p_service_obj->type, - &uuid, - &p_service_obj->handle) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service."))); - } - } else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) { - BLE_DRIVER_LOG("adding service\n"); - - ble_uuid_t uuid; - uuid.type = p_service_obj->p_uuid->type; - uuid.uuid = p_service_obj->p_uuid->value[0]; - uuid.uuid += p_service_obj->p_uuid->value[1] << 8; + } - if (sd_ble_gatts_service_add(p_service_obj->type, - &uuid, - &p_service_obj->handle) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service."))); - } + uint32_t err_code = sd_ble_gatts_service_add(p_service_obj->type, + &uuid, + &p_service_obj->handle); + if (err_code != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Can not add Service. status: 0x%08lX"), err_code)); } + return true; } -bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) { +bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) { ble_gatts_char_md_t char_md; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; @@ -310,24 +298,19 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) { memset(&char_md, 0, sizeof(char_md)); - char_md.char_props.broadcast = (p_char_obj->props & UBLUEPY_PROP_BROADCAST) ? 1 : 0; - char_md.char_props.read = (p_char_obj->props & UBLUEPY_PROP_READ) ? 1 : 0; - char_md.char_props.write_wo_resp = (p_char_obj->props & UBLUEPY_PROP_WRITE_WO_RESP) ? 1 : 0; - char_md.char_props.write = (p_char_obj->props & UBLUEPY_PROP_WRITE) ? 1 : 0; - char_md.char_props.notify = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0; - char_md.char_props.indicate = (p_char_obj->props & UBLUEPY_PROP_INDICATE) ? 1 : 0; -#if 0 - char_md.char_props.auth_signed_wr = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0; -#endif - + char_md.char_props.broadcast = characteristic->props.broadcast; + char_md.char_props.read = characteristic->props.read; + char_md.char_props.write_wo_resp = characteristic->props.write_wo_resp; + char_md.char_props.write = characteristic->props.write; + char_md.char_props.notify = characteristic->props.notify; + char_md.char_props.indicate = characteristic->props.indicate; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_sccd_md = NULL; - // if cccd - if (p_char_obj->attrs & UBLUEPY_ATTR_CCCD) { + if (characteristic->props.notify || characteristic->props.notify) { memset(&cccd_md, 0, sizeof(cccd_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); @@ -337,9 +320,12 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) { char_md.p_cccd_md = NULL; } - uuid.type = p_char_obj->p_uuid->type; - uuid.uuid = p_char_obj->p_uuid->value[0]; - uuid.uuid += p_char_obj->p_uuid->value[1] << 8; + uuid.type = BLE_UUID_TYPE_BLE; + if (characteristic->uuid->type == UUID_TYPE_128BIT) + uuid.type = characteristic->uuid->uuid_vs_idx; + + uuid.uuid = characteristic->uuid->value[0]; + uuid.uuid += characteristic->uuid->value[1] << 8; memset(&attr_md, 0, sizeof(attr_md)); @@ -365,19 +351,20 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) { ble_gatts_char_handles_t handles; - if (sd_ble_gatts_characteristic_add(p_char_obj->service_handle, - &char_md, - &attr_char_value, - &handles) != 0) { + uint32_t err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle, + &char_md, + &attr_char_value, + &handles); + if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Characteristic."))); + translate("Can not add Characteristic. status: 0x%08lX"), err_code)); } // apply handles to object instance - p_char_obj->handle = handles.value_handle; - p_char_obj->user_desc_handle = handles.user_desc_handle; - p_char_obj->cccd_handle = handles.cccd_handle; - p_char_obj->sccd_handle = handles.sccd_handle; + characteristic->handle = handles.value_handle; + characteristic->user_desc_handle = handles.user_desc_handle; + characteristic->cccd_handle = handles.cccd_handle; + characteristic->sccd_handle = handles.sccd_handle; return true; } @@ -652,15 +639,18 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui } -void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { +void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); + uint16_t conn_handle = service->p_periph->conn_handle; ble_gatts_value_t gatts_value; + memset(&gatts_value, 0, sizeof(gatts_value)); - gatts_value.len = len; + gatts_value.len = bufinfo->len; gatts_value.offset = 0; - gatts_value.p_value = p_data; + gatts_value.p_value = bufinfo->buf; - uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value); + uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, @@ -668,17 +658,19 @@ void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, u } } -void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { - uint16_t hvx_len = len; +void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); + uint16_t conn_handle = service->p_periph->conn_handle; ble_gatts_hvx_params_t hvx_params; + uint16_t hvx_len = bufinfo->len; memset(&hvx_params, 0, sizeof(hvx_params)); - hvx_params.handle = handle; + hvx_params.handle = characteristic->handle; hvx_params.type = BLE_GATT_HVX_NOTIFICATION; hvx_params.offset = 0; hvx_params.p_len = &hvx_len; - hvx_params.p_data = p_data; + hvx_params.p_data = bufinfo->buf; while (m_tx_in_progress) { ; @@ -713,13 +705,13 @@ void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_c } -void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb) { - - mp_gattc_char_data_observer = obj; +void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) { + ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); + mp_gattc_char_data_observer = characteristic; gattc_char_data_handle = cb; - uint32_t err_code = sd_ble_gattc_read(conn_handle, - handle, + const uint32_t err_code = sd_ble_gattc_read(service->p_periph->conn_handle, + characteristic->handle, 0); if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, @@ -731,26 +723,26 @@ void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, bl } } -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response) { +void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); + uint16_t conn_handle = service->p_periph->conn_handle; ble_gattc_write_params_t write_params; + write_params.write_op = BLE_GATT_OP_WRITE_REQ; - if (w_response) { - write_params.write_op = BLE_GATT_OP_WRITE_REQ; - } else { + if (characteristic->props.write_wo_resp) { write_params.write_op = BLE_GATT_OP_WRITE_CMD; } write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; - write_params.handle = handle; + write_params.handle = characteristic->handle; write_params.offset = 0; - write_params.len = len; - write_params.p_value = p_data; + write_params.len = bufinfo->len; + write_params.p_value = bufinfo->buf; - m_write_done = !w_response; + m_write_done = (write_params.write_op == BLE_GATT_OP_WRITE_CMD); uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); - if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); @@ -1053,15 +1045,12 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) { char_data.decl_handle = p_char->handle_decl; char_data.value_handle = p_char->handle_value; - char_data.props |= (p_char->char_props.broadcast) ? UBLUEPY_PROP_BROADCAST : 0; - char_data.props |= (p_char->char_props.read) ? UBLUEPY_PROP_READ : 0; - char_data.props |= (p_char->char_props.write_wo_resp) ? UBLUEPY_PROP_WRITE_WO_RESP : 0; - char_data.props |= (p_char->char_props.write) ? UBLUEPY_PROP_WRITE : 0; - char_data.props |= (p_char->char_props.notify) ? UBLUEPY_PROP_NOTIFY : 0; - char_data.props |= (p_char->char_props.indicate) ? UBLUEPY_PROP_INDICATE : 0; - #if 0 - char_data.props |= (p_char->char_props.auth_signed_wr) ? UBLUEPY_PROP_NOTIFY : 0; - #endif + char_data.props.broadcast = p_char->char_props.broadcast; + char_data.props.read = p_char->char_props.read; + char_data.props.write_wo_resp = p_char->char_props.write_wo_resp; + char_data.props.write = p_char->char_props.write; + char_data.props.notify = p_char->char_props.notify; + char_data.props.indicate = p_char->char_props.indicate; disc_add_char_handler(mp_gattc_disc_char_observer, &char_data); } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index d344e2690..7283dbfce 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -32,6 +32,7 @@ #include #include +#include "shared-module/bleio/Characteristic.h" #include "shared-module/bleio/Scanner.h" #include "modubluepy.h" @@ -61,7 +62,14 @@ typedef struct { typedef struct { uint16_t uuid; uint8_t uuid_type; - uint8_t props; + struct { + bool broadcast : 1; + bool read : 1; + bool write_wo_resp : 1; + bool write : 1; + bool notify : 1; + bool indicate : 1; + } props; uint16_t decl_handle; uint16_t value_handle; } ble_drv_char_data_t; @@ -72,7 +80,7 @@ typedef void (*ble_drv_gattc_evt_callback_t)(mp_obj_t self, uint16_t event_id, u typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data); typedef void (*ble_drv_disc_add_service_callback_t)(mp_obj_t self, ble_drv_service_data_t * p_service_data); typedef void (*ble_drv_disc_add_char_callback_t)(mp_obj_t self, ble_drv_char_data_t * p_desc_data); -typedef void (*ble_drv_gattc_char_data_callback_t)(mp_obj_t self, uint16_t length, uint8_t * p_data); +typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); uint32_t ble_drv_stack_enable(void); @@ -86,7 +94,7 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx); bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj); -bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj); +bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic); bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params); @@ -100,13 +108,13 @@ void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); -void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb); +void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb); -void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); +void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); -void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); +void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response); +void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); void ble_drv_scan_start(uint16_t interval, uint16_t window); diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index 1470f4a37..2d1a6a550 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -30,7 +30,6 @@ extern const mp_obj_type_t ubluepy_peripheral_type; extern const mp_obj_type_t ubluepy_service_type; -extern const mp_obj_type_t ubluepy_characteristic_type; STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, @@ -38,7 +37,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) }, #endif { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, - { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&ubluepy_characteristic_type) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table); diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index 5d80e3536..ad33001cb 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -75,7 +75,6 @@ p.advertise(device_name="micr", services=[s]) #include "py/obj.h" extern const mp_obj_type_t ubluepy_service_type; -extern const mp_obj_type_t ubluepy_characteristic_type; extern const mp_obj_type_t ubluepy_peripheral_type; typedef enum { @@ -116,20 +115,6 @@ typedef struct _ubluepy_service_obj_t { uint16_t end_handle; } ubluepy_service_obj_t; -typedef struct _ubluepy_characteristic_obj_t { - mp_obj_base_t base; - uint16_t handle; - bleio_uuid_obj_t * p_uuid; - uint16_t service_handle; - uint16_t user_desc_handle; - uint16_t cccd_handle; - uint16_t sccd_handle; - uint8_t props; - uint8_t attrs; - ubluepy_service_obj_t * p_service; - mp_obj_t value_data; -} ubluepy_characteristic_obj_t; - typedef struct _ubluepy_advertise_data_t { uint8_t * p_device_name; uint8_t device_name_len; diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c deleted file mode 100644 index e0259fb06..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" -#include "ble_drv.h" -#include "shared-bindings/bleio/UUID.h" - -STATIC void ubluepy_characteristic_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_characteristic_obj_t * self = (ubluepy_characteristic_obj_t *)o; - - mp_printf(print, "Characteristic(handle: 0x" HEX2_FMT ", conn_handle: " HEX2_FMT ")", - self->handle, self->p_service->p_periph->conn_handle); -} - -STATIC mp_obj_t ubluepy_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_props, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UBLUEPY_PROP_READ | UBLUEPY_PROP_WRITE} }, - { MP_QSTR_attrs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_characteristic_obj_t *s = m_new_obj(ubluepy_characteristic_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[0].u_obj; - - if (uuid_obj == mp_const_none) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { - s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); - // (void)sd_characterstic_add(s); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - if (args[1].u_int > 0) { - s->props = (uint8_t)args[1].u_int; - } - - if (args[2].u_int > 0) { - s->attrs = (uint8_t)args[2].u_int; - } - - // clear pointer to service - s->p_service = NULL; - - // clear pointer to char value data - s->value_data = NULL; - - return MP_OBJ_FROM_PTR(s); -} - -void char_data_callback(mp_obj_t self_in, uint16_t length, uint8_t * p_data) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - self->value_data = mp_obj_new_bytearray(length, p_data); -} - -/// \method read() -/// Read Characteristic value. -/// -STATIC mp_obj_t char_read(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - -#if MICROPY_PY_UBLUEPY_CENTRAL - // TODO: free any previous allocation of value_data - - ble_drv_attr_c_read(self->p_service->p_periph->conn_handle, - self->handle, - self_in, - char_data_callback); - - return self->value_data; -#else - (void)self; - return mp_const_none; -#endif -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_read_obj, char_read); - -/// \method write(data, [with_response=False]) -/// Write Characteristic value. -/// -STATIC mp_obj_t char_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - ubluepy_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t data = pos_args[1]; - - static const mp_arg_t allowed_args[] = { - { MP_QSTR_with_response, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - - // figure out mode of the Peripheral - ubluepy_role_type_t role = self->p_service->p_periph->role; - - if (role == UBLUEPY_ROLE_PERIPHERAL) { - if (self->props & UBLUEPY_PROP_NOTIFY) { - ble_drv_attr_s_notify(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf); - } else { - ble_drv_attr_s_write(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf); - } - } else { -#if MICROPY_PY_UBLUEPY_CENTRAL - bool with_response = args[0].u_bool; - - ble_drv_attr_c_write(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf, - with_response); -#endif - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_characteristic_write_obj, 2, char_write); - -/// \method properties() -/// Read Characteristic value properties. -/// -STATIC mp_obj_t char_properties(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(self->props); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_get_properties_obj, char_properties); - -/// \method uuid() -/// Get UUID instance of the characteristic. -/// -STATIC mp_obj_t char_uuid(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_FROM_PTR(self->p_uuid); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_get_uuid_obj, char_uuid); - - -STATIC const mp_rom_map_elem_t ubluepy_characteristic_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&ubluepy_characteristic_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&ubluepy_characteristic_write_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_supportsRead), MP_ROM_PTR(&ubluepy_characteristic_supports_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_propertiesToString), MP_ROM_PTR(&ubluepy_characteristic_properties_to_str_obj) }, - { MP_ROM_QSTR(MP_QSTR_getHandle), MP_ROM_PTR(&ubluepy_characteristic_get_handle_obj) }, - - // Properties - { MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_characteristic_get_peripheral_obj) }, -#endif - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_characteristic_get_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&ubluepy_characteristic_get_properties_obj) }, - - { MP_ROM_QSTR(MP_QSTR_PROP_BROADCAST), MP_ROM_INT(UBLUEPY_PROP_BROADCAST) }, - { MP_ROM_QSTR(MP_QSTR_PROP_READ), MP_ROM_INT(UBLUEPY_PROP_READ) }, - { MP_ROM_QSTR(MP_QSTR_PROP_WRITE_WO_RESP), MP_ROM_INT(UBLUEPY_PROP_WRITE_WO_RESP) }, - { MP_ROM_QSTR(MP_QSTR_PROP_WRITE), MP_ROM_INT(UBLUEPY_PROP_WRITE) }, - { MP_ROM_QSTR(MP_QSTR_PROP_NOTIFY), MP_ROM_INT(UBLUEPY_PROP_NOTIFY) }, - { MP_ROM_QSTR(MP_QSTR_PROP_INDICATE), MP_ROM_INT(UBLUEPY_PROP_INDICATE) }, - { MP_ROM_QSTR(MP_QSTR_PROP_AUTH_SIGNED_WR), MP_ROM_INT(UBLUEPY_PROP_AUTH_SIGNED_WR) }, - -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_ATTR_CCCD), MP_ROM_INT(UBLUEPY_ATTR_CCCD) }, -#endif - -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_PROP_AUTH_SIGNED_WR), MP_ROM_INT(UBLUEPY_ATTR_SCCD) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_characteristic_locals_dict, ubluepy_characteristic_locals_dict_table); - -const mp_obj_type_t ubluepy_characteristic_type = { - { &mp_type_type }, - .name = MP_QSTR_Characteristic, - .print = ubluepy_characteristic_print, - .make_new = ubluepy_characteristic_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_characteristic_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 6fced1695..2a826db4d 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -34,6 +34,7 @@ #include "ble_drv.h" #include "common-hal/bleio/UUID.h" +#include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/UUID.h" STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { @@ -316,26 +317,31 @@ void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_d void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data) { ubluepy_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in); - ubluepy_characteristic_obj_t * p_char = m_new_obj(ubluepy_characteristic_obj_t); - p_char->base.type = &ubluepy_characteristic_type; + bleio_characteristic_obj_t * p_char = m_new_obj(bleio_characteristic_obj_t); + p_char->base.type = &bleio_characteristic_type; bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); p_uuid->base.type = &bleio_uuid_type; - p_char->p_uuid = p_uuid; + p_char->uuid = p_uuid; p_uuid->type = p_desc_data->uuid_type; p_uuid->value[0] = p_desc_data->uuid & 0xFF; p_uuid->value[1] = p_desc_data->uuid >> 8; // add characteristic specific data from discovery - p_char->props = p_desc_data->props; + p_char->props.broadcast = p_desc_data->props.broadcast; + p_char->props.indicate = p_desc_data->props.indicate; + p_char->props.notify = p_desc_data->props.notify; + p_char->props.read = p_desc_data->props.read; + p_char->props.write = p_desc_data->props.write; + p_char->props.write_wo_resp = p_desc_data->props.write_wo_resp; p_char->handle = p_desc_data->value_handle; // equivalent to ubluepy_service.c - service_add_characteristic() // except the registration of the characteristic towards the bluetooth stack p_char->service_handle = p_service->handle; - p_char->p_service = p_service; + p_char->service = p_service; mp_obj_list_append(p_service->char_list, MP_OBJ_FROM_PTR(p_char)); } @@ -430,7 +436,7 @@ STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, m mp_uint_t num_chars; mp_obj_get_array(p_service->char_list, &num_chars, &characteristics); - ubluepy_characteristic_obj_t * p_char = (ubluepy_characteristic_obj_t *)characteristics[num_chars - 1]; + bleio_characteristic_obj_t * p_char = (bleio_characteristic_obj_t *)characteristics[num_chars - 1]; uint16_t next_handle = p_char->handle + 1; if ((next_handle) < p_service->end_handle) { char_disc_retval = ble_drv_discover_characteristic(p_service, diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c index 69d98bb7e..3834c61de 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ b/ports/nrf/modules/ubluepy/ubluepy_service.c @@ -94,14 +94,13 @@ STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_arg /// STATIC mp_obj_t service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic) { ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_characteristic_obj_t * p_char = MP_OBJ_TO_PTR(characteristic); + bleio_characteristic_obj_t * p_char = MP_OBJ_TO_PTR(characteristic); p_char->service_handle = self->handle; bool retval = ble_drv_characteristic_add(p_char); - if (retval) { - p_char->p_service = self; + p_char->service = self_in; } mp_obj_list_append(self->char_list, characteristic); @@ -139,10 +138,10 @@ STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) { mp_obj_get_array(self->char_list, &num_chars, &chars); for (uint8_t i = 0; i < num_chars; i++) { - ubluepy_characteristic_obj_t * p_char = (ubluepy_characteristic_obj_t *)chars[i]; + bleio_characteristic_obj_t * p_char = (bleio_characteristic_obj_t *)chars[i]; - bool type_match = p_char->p_uuid->type == p_uuid->type; - bool uuid_match = ((uint16_t)(*(uint16_t *)&p_char->p_uuid->value[0]) == + bool type_match = p_char->uuid->type == p_uuid->type; + bool uuid_match = ((uint16_t)(*(uint16_t *)&p_char->uuid->value[0]) == (uint16_t)(*(uint16_t *)&p_uuid->value[0])); if (type_match && uuid_match) { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c new file mode 100644 index 000000000..fb96be703 --- /dev/null +++ b/shared-bindings/bleio/Characteristic.c @@ -0,0 +1,330 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Characteristic` -- BLE service characteristic +//| ========================================================= +//| +//| Stores information about a BLE service characteristic and allows to read +//| and write the characteristic's value. +//| + +//| .. class:: Characteristic(uuid) +//| +//| Create a new Characteristic object identified by the specified UUID. +//| +//| :param uuid: The uuid of the characteristic +//| + +//| .. attribute:: broadcast +//| +//| A `bool` specifying if the characteristic allows broadcasting its value. +//| + +//| .. attribute:: indicate +//| +//| A `bool` specifying if the characteristic allows indicating its value. +//| + +//| .. attribute:: notify +//| +//| A `bool` specifying if the characteristic allows notifying its value. +//| + +//| .. attribute:: read +//| +//| A `bool` specifying if the characteristic allows reading its value. +//| + +//| .. attribute:: uuid +//| +//| The UUID of this characteristic. (read-only) +//| + +//| .. attribute:: value +//| +//| The value of this characteristic. The value can be written to if the `write` property allows it. +//| If the `read` property allows it, the value can be read. If the `notify` property is set, writting +//| to the value will generate a BLE notification. +//| + +//| .. attribute:: write +//| +//| A `bool` specifying if the characteristic allows writting to its value. +//| + +//| .. attribute:: write_no_resp +//| +//| A `bool` specifying if the characteristic allows writting to its value without response. +//| +STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Characteristic(uuid: 0x"HEX2_FMT""HEX2_FMT" handle: 0x" HEX2_FMT ")", + self->uuid->value[0], self->uuid->value[1], self->handle); +} + +STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); + self->base.type = &bleio_characteristic_type; + self->service = mp_const_none; + self->value_data = NULL; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + 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); + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + if (uuid == mp_const_none) { + return MP_OBJ_FROM_PTR(self); + } + + if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { + self->uuid = MP_OBJ_TO_PTR(uuid); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Invalid UUID parameter")); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.broadcast); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); + +STATIC mp_obj_t bleio_characteristic_set_broadcast(mp_obj_t self_in, mp_obj_t broadcast_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.broadcast = mp_obj_is_true(broadcast_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_broadcast_obj, bleio_characteristic_set_broadcast); + +const mp_obj_property_t bleio_characteristic_broadcast_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj, + (mp_obj_t)&bleio_characteristic_set_broadcast_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.indicate); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate); + +STATIC mp_obj_t bleio_characteristic_set_indicate(mp_obj_t self_in, mp_obj_t indicate_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.indicate = mp_obj_is_true(indicate_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_indicate_obj, bleio_characteristic_set_indicate); + +const mp_obj_property_t bleio_characteristic_indicate_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj, + (mp_obj_t)&bleio_characteristic_set_indicate_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.notify); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify); + +STATIC mp_obj_t bleio_characteristic_set_notify(mp_obj_t self_in, mp_obj_t notify_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.notify = mp_obj_is_true(notify_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_notify_obj, bleio_characteristic_set_notify); + +const mp_obj_property_t bleio_characteristic_notify_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj, + (mp_obj_t)&bleio_characteristic_set_notify_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.read); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read); + +STATIC mp_obj_t bleio_characteristic_set_read(mp_obj_t self_in, mp_obj_t read_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.read = mp_obj_is_true(read_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_read_obj, bleio_characteristic_set_read); + +const mp_obj_property_t bleio_characteristic_read_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj, + (mp_obj_t)&bleio_characteristic_set_read_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.write); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write); + +STATIC mp_obj_t bleio_characteristic_set_write(mp_obj_t self_in, mp_obj_t write_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.write = mp_obj_is_true(write_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_obj, bleio_characteristic_set_write); + +const mp_obj_property_t bleio_characteristic_write_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj, + (mp_obj_t)&bleio_characteristic_set_write_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_write_wo_resp(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.write_wo_resp); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_wo_resp_obj, bleio_characteristic_get_write_wo_resp); + +STATIC mp_obj_t bleio_characteristic_set_write_wo_resp(mp_obj_t self_in, mp_obj_t write_wo_resp_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.write_wo_resp = mp_obj_is_true(write_wo_resp_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_wo_resp_obj, bleio_characteristic_set_write_wo_resp); + +const mp_obj_property_t bleio_characteristic_write_wo_resp_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_write_wo_resp_obj, + (mp_obj_t)&bleio_characteristic_set_write_wo_resp_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_FROM_PTR(self->uuid); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid); + +const mp_obj_property_t bleio_characteristic_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_characteristic_read_value(self); + + return self->value_data; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value); + +STATIC mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_characteristic_write_value(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_value_obj, bleio_characteristic_set_value); + +const mp_obj_property_t bleio_characteristic_value_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_value_obj, + (mp_obj_t)&bleio_characteristic_set_value_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) }, + { MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) }, + { MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_wo_resp), MP_ROM_PTR(&bleio_characteristic_write_wo_resp_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table); + +const mp_obj_type_t bleio_characteristic_type = { + { &mp_type_type }, + .name = MP_QSTR_Characteristic, + .print = bleio_characteristic_print, + .make_new = bleio_characteristic_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict +}; diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h new file mode 100644 index 000000000..dd67170d9 --- /dev/null +++ b/shared-bindings/bleio/Characteristic.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H + +#include "shared-module/bleio/Characteristic.h" + +extern const mp_obj_type_t bleio_characteristic_type; + +extern void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 4ad858ac9..f96abc449 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -30,6 +30,7 @@ #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/AdvertisementData.h" +#include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" @@ -54,6 +55,7 @@ //| AddressType //| AdvertisementData //| Adapter +//| Characteristic //| Descriptor //| ScanEntry //| Scanner @@ -71,6 +73,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, + { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h new file mode 100644 index 000000000..aa313afd3 --- /dev/null +++ b/shared-module/bleio/Characteristic.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H + +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t service; + uint16_t service_handle; + bleio_uuid_obj_t *uuid; + mp_obj_t value_data; + uint16_t handle; + struct { + bool broadcast : 1; + bool read : 1; + bool write_wo_resp : 1; + bool write : 1; + bool notify : 1; + bool indicate : 1; + } props; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; +} bleio_characteristic_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H -- cgit v1.2.3 From bda734223e75382be048d47fa9331afd7e9cfdce Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 01:01:41 +0200 Subject: nrf: Move the Service class from ubluepy to the shared bleio module --- ports/nrf/Makefile | 2 +- ports/nrf/common-hal/bleio/Characteristic.c | 4 +- ports/nrf/common-hal/bleio/Service.c | 38 +++++ ports/nrf/drivers/bluetooth/ble_drv.c | 71 +++++----- ports/nrf/drivers/bluetooth/ble_drv.h | 3 +- ports/nrf/modules/ubluepy/modubluepy.c | 1 - ports/nrf/modules/ubluepy/modubluepy.h | 17 --- ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 17 +-- ports/nrf/modules/ubluepy/ubluepy_service.c | 188 ------------------------- shared-bindings/bleio/Characteristic.c | 4 +- shared-bindings/bleio/Service.c | 167 ++++++++++++++++++++++ shared-bindings/bleio/Service.h | 38 +++++ shared-bindings/bleio/__init__.c | 4 +- shared-module/bleio/Characteristic.h | 3 +- shared-module/bleio/Service.h | 44 ++++++ 15 files changed, 346 insertions(+), 255 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Service.c delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_service.c create mode 100644 shared-bindings/bleio/Service.c create mode 100644 shared-bindings/bleio/Service.h create mode 100644 shared-module/bleio/Service.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 6ed2d3054..6112678f5 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -130,7 +130,6 @@ SRC_C += \ DRIVERS_SRC_C += $(addprefix modules/,\ ubluepy/modubluepy.c \ ubluepy/ubluepy_peripheral.c \ - ubluepy/ubluepy_service.c \ ) SRC_COMMON_HAL += \ @@ -165,6 +164,7 @@ SRC_COMMON_HAL += \ bleio/Characteristic.c \ bleio/Descriptor.c \ bleio/Scanner.c \ + bleio/Service.c \ bleio/UUID.c endif diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 3087b6707..56afc52c5 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -36,8 +36,8 @@ void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self } void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(self->service); - ubluepy_role_type_t role = service->p_periph->role; + ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(self->service->periph); + ubluepy_role_type_t role = peripheral->role; if (role == UBLUEPY_ROLE_PERIPHERAL) { // TODO: Add indications diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c new file mode 100644 index 000000000..b6e0595b1 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Service.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 "ble_drv.h" +#include "shared-module/bleio/Service.h" + +void common_hal_bleio_service_construct(bleio_service_obj_t *self) { + ble_drv_service_add(self); +} + +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { + if (ble_drv_characteristic_add(characteristic)) { + characteristic->service = self; + } +} diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 6240a18e4..e421036ae 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -267,26 +267,29 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) { return true; } -bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) { +void ble_drv_service_add(bleio_service_obj_t *service) { SD_TEST_OR_ENABLE(); - ble_uuid_t uuid; - uuid.type = BLE_UUID_TYPE_BLE; - uuid.uuid = p_service_obj->p_uuid->value[0] | (p_service_obj->p_uuid->value[1] << 8); + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) + }; - if (p_service_obj->p_uuid->type == UUID_TYPE_128BIT) { - uuid.type = p_service_obj->p_uuid->uuid_vs_idx; + if (service->uuid->type == UUID_TYPE_128BIT) { + uuid.type = service->uuid->uuid_vs_idx; } - uint32_t err_code = sd_ble_gatts_service_add(p_service_obj->type, - &uuid, - &p_service_obj->handle); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service. status: 0x%08lX"), err_code)); + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (service->is_secondary) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; } - return true; + if (sd_ble_gatts_service_add(service_type, + &uuid, + &service->handle) != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Can not add Service."))); + } } bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) { @@ -320,7 +323,7 @@ bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) { char_md.p_cccd_md = NULL; } - uuid.type = BLE_UUID_TYPE_BLE; + uuid.type = BLE_UUID_TYPE_BLE; if (characteristic->uuid->type == UUID_TYPE_128BIT) uuid.type = characteristic->uuid->uuid_vs_idx; @@ -416,12 +419,12 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { bool type_128bit_present = false; for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; - if (p_service->p_uuid->type == UUID_TYPE_16BIT) { + bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; + if (p_service->uuid->type == UUID_TYPE_16BIT) { type_16bit_present = true; } - if (p_service->p_uuid->type == UUID_TYPE_128BIT) { + if (p_service->uuid->type == UUID_TYPE_128BIT) { type_128bit_present = true; } } @@ -439,12 +442,12 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { uint8_t encoded_size = 0; for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; + bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; ble_uuid_t uuid; - uuid.type = p_service->p_uuid->type; - uuid.uuid = p_service->p_uuid->value[0]; - uuid.uuid += p_service->p_uuid->value[1] << 8; + uuid.type = p_service->uuid->type; + uuid.uuid = p_service->uuid->value[0]; + uuid.uuid += p_service->uuid->value[1] << 8; // calculate total size of uuids if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, @@ -488,12 +491,12 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { uint8_t encoded_size = 0; for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; + bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; ble_uuid_t uuid; - uuid.type = p_service->p_uuid->uuid_vs_idx; - uuid.uuid = p_service->p_uuid->value[0]; - uuid.uuid += p_service->p_uuid->value[1] << 8; + uuid.type = p_service->uuid->uuid_vs_idx; + uuid.uuid = p_service->uuid->value[0]; + uuid.uuid += p_service->uuid->value[1] << 8; // calculate total size of uuids if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { @@ -640,8 +643,8 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui } void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); - uint16_t conn_handle = service->p_periph->conn_handle; + ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); + uint16_t conn_handle = peripheral->conn_handle; ble_gatts_value_t gatts_value; memset(&gatts_value, 0, sizeof(gatts_value)); @@ -659,8 +662,8 @@ void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_ } void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); - uint16_t conn_handle = service->p_periph->conn_handle; + ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); + uint16_t conn_handle = peripheral->conn_handle; ble_gatts_hvx_params_t hvx_params; uint16_t hvx_len = bufinfo->len; @@ -706,11 +709,13 @@ void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_c void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) { - ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); + bleio_service_obj_t *service = characteristic->service; + ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(service->periph); + mp_gattc_char_data_observer = characteristic; gattc_char_data_handle = cb; - const uint32_t err_code = sd_ble_gattc_read(service->p_periph->conn_handle, + const uint32_t err_code = sd_ble_gattc_read(peripheral->conn_handle, characteristic->handle, 0); if (err_code != 0) { @@ -724,8 +729,8 @@ void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gat } void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_service_obj_t *service = MP_OBJ_TO_PTR(characteristic->service); - uint16_t conn_handle = service->p_periph->conn_handle; + ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); + uint16_t conn_handle = peripheral->conn_handle; ble_gattc_write_params_t write_params; write_params.write_op = BLE_GATT_OP_WRITE_REQ; diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index 7283dbfce..8c6bd6ce3 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -34,6 +34,7 @@ #include "shared-module/bleio/Characteristic.h" #include "shared-module/bleio/Scanner.h" +#include "shared-module/bleio/Service.h" #include "modubluepy.h" @@ -92,7 +93,7 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr); bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx); -bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj); +void ble_drv_service_add(bleio_service_obj_t *service); bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic); diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c index 2d1a6a550..f8266a82d 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ b/ports/nrf/modules/ubluepy/modubluepy.c @@ -36,7 +36,6 @@ STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { #if MICROPY_PY_UBLUEPY_PERIPHERAL { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) }, #endif - { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table); diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h index ad33001cb..e301f0476 100644 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ b/ports/nrf/modules/ubluepy/modubluepy.h @@ -74,14 +74,8 @@ p.advertise(device_name="micr", services=[s]) #include "common-hal/bleio/UUID.h" #include "py/obj.h" -extern const mp_obj_type_t ubluepy_service_type; extern const mp_obj_type_t ubluepy_peripheral_type; -typedef enum { - UBLUEPY_SERVICE_PRIMARY = 1, - UBLUEPY_SERVICE_SECONDARY = 2 -} ubluepy_service_type_t; - typedef enum { UBLUEPY_ADDR_TYPE_PUBLIC = 0, UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1, @@ -104,17 +98,6 @@ typedef struct _ubluepy_peripheral_obj_t { mp_obj_t service_list; } ubluepy_peripheral_obj_t; -typedef struct _ubluepy_service_obj_t { - mp_obj_base_t base; - uint16_t handle; - uint8_t type; - bleio_uuid_obj_t * p_uuid; - ubluepy_peripheral_obj_t * p_periph; - mp_obj_t char_list; - uint16_t start_handle; - uint16_t end_handle; -} ubluepy_service_obj_t; - typedef struct _ubluepy_advertise_data_t { uint8_t * p_device_name; uint8_t device_name_len; diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c index 2a826db4d..3b1a0d279 100644 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c @@ -35,6 +35,7 @@ #include "ble_drv.h" #include "common-hal/bleio/UUID.h" #include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { @@ -271,9 +272,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_disconnect_obj, peripheral_d /// STATIC mp_obj_t peripheral_add_service(mp_obj_t self_in, mp_obj_t service) { ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_service_obj_t * p_service = MP_OBJ_TO_PTR(service); + bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service); - p_service->p_periph = self; + p_service->periph = self_in; mp_obj_list_append(self->service_list, service); @@ -294,13 +295,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_get_services_obj, peripheral #if MICROPY_PY_UBLUEPY_CENTRAL void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_data) { - ubluepy_service_obj_t * p_service = m_new_obj(ubluepy_service_obj_t); - p_service->base.type = &ubluepy_service_type; + bleio_service_obj_t * p_service = m_new_obj(bleio_service_obj_t); + p_service->base.type = &bleio_service_type; bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); p_uuid->base.type = &bleio_uuid_type; - p_service->p_uuid = p_uuid; + p_service->uuid = p_uuid; p_uuid->type = p_service_data->uuid_type; p_uuid->value[0] = p_service_data->uuid & 0xFF; @@ -316,7 +317,7 @@ void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_d } void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data) { - ubluepy_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in); + bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in); bleio_characteristic_obj_t * p_char = m_new_obj(bleio_characteristic_obj_t); p_char->base.type = &bleio_characteristic_type; @@ -410,7 +411,7 @@ STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, m mp_uint_t num_services; mp_obj_get_array(self->service_list, &num_services, &services); - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)services[num_services - 1]; + bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[num_services - 1]; service_disc_retval = ble_drv_discover_services(self, self->conn_handle, @@ -424,7 +425,7 @@ STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, m mp_obj_get_array(self->service_list, &num_services, &services); for (uint16_t s = 0; s < num_services; s++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)services[s]; + bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[s]; bool char_disc_retval = ble_drv_discover_characteristic(p_service, self->conn_handle, p_service->start_handle, diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c deleted file mode 100644 index 3834c61de..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objlist.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" -#include "ble_drv.h" -#include "common-hal/bleio/UUID.h" -#include "shared-bindings/bleio/UUID.h" - -STATIC void ubluepy_service_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_service_obj_t * self = (ubluepy_service_obj_t *)o; - - mp_printf(print, "Service(handle: 0x" HEX2_FMT ")", self->handle); -} - -STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID, ARG_NEW_TYPE }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { ARG_NEW_TYPE, MP_ARG_INT, {.u_int = UBLUEPY_SERVICE_PRIMARY} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_service_obj_t *s = m_new_obj(ubluepy_service_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - if (uuid_obj == MP_OBJ_NULL) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { - s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); - - uint8_t type = args[ARG_NEW_TYPE].u_int; - if (type > 0 && type <= UBLUEPY_SERVICE_PRIMARY) { - s->type = type; - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid Service type"))); - } - - (void)ble_drv_service_add(s); - - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - // clear reference to peripheral - s->p_periph = NULL; - s->char_list = mp_obj_new_list(0, NULL); - - return MP_OBJ_FROM_PTR(s); -} - -/// \method addCharacteristic(Characteristic) -/// Add Characteristic to the Service. -/// -STATIC mp_obj_t service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - bleio_characteristic_obj_t * p_char = MP_OBJ_TO_PTR(characteristic); - - p_char->service_handle = self->handle; - - bool retval = ble_drv_characteristic_add(p_char); - if (retval) { - p_char->service = self_in; - } - - mp_obj_list_append(self->char_list, characteristic); - - // return mp_obj_new_bool(retval); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_service_add_char_obj, service_add_characteristic); - -/// \method getCharacteristics() -/// Return list with all characteristics registered in the Service. -/// -STATIC mp_obj_t service_get_chars(mp_obj_t self_in) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - - return self->char_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_service_get_chars_obj, service_get_chars); - -/// \method getCharacteristic(UUID) -/// Return Characteristic with the given UUID. -/// -STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - bleio_uuid_obj_t * p_uuid = MP_OBJ_TO_PTR(uuid); - - // validate that there is an UUID object passed in as parameter - if (!(MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type))) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - mp_obj_t * chars = NULL; - mp_uint_t num_chars = 0; - mp_obj_get_array(self->char_list, &num_chars, &chars); - - for (uint8_t i = 0; i < num_chars; i++) { - bleio_characteristic_obj_t * p_char = (bleio_characteristic_obj_t *)chars[i]; - - bool type_match = p_char->uuid->type == p_uuid->type; - bool uuid_match = ((uint16_t)(*(uint16_t *)&p_char->uuid->value[0]) == - (uint16_t)(*(uint16_t *)&p_uuid->value[0])); - - if (type_match && uuid_match) { - return MP_OBJ_FROM_PTR(p_char); - } - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_service_get_char_obj, service_get_characteristic); - -/// \method uuid() -/// Get UUID instance of the Service. -/// -STATIC mp_obj_t service_uuid(mp_obj_t self_in) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_FROM_PTR(self->p_uuid); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_service_get_uuid_obj, service_uuid); - -STATIC const mp_rom_map_elem_t ubluepy_service_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_getCharacteristic), MP_ROM_PTR(&ubluepy_service_get_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_service_add_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_service_get_chars_obj) }, -#if 0 - // Properties - { MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_service_get_peripheral_obj) }, -#endif - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_service_get_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_PRIMARY), MP_ROM_INT(UBLUEPY_SERVICE_PRIMARY) }, - { MP_ROM_QSTR(MP_QSTR_SECONDARY), MP_ROM_INT(UBLUEPY_SERVICE_SECONDARY) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_service_locals_dict, ubluepy_service_locals_dict_table); - -const mp_obj_type_t ubluepy_service_type = { - { &mp_type_type }, - .name = MP_QSTR_Service, - .print = ubluepy_service_print, - .make_new = ubluepy_service_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_service_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index fb96be703..97aed679e 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -91,14 +91,14 @@ STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "Characteristic(uuid: 0x"HEX2_FMT""HEX2_FMT" handle: 0x" HEX2_FMT ")", - self->uuid->value[0], self->uuid->value[1], self->handle); + self->uuid->value[1], self->uuid->value[0], self->handle); } STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); self->base.type = &bleio_characteristic_type; - self->service = mp_const_none; + self->service = NULL; self->value_data = NULL; mp_map_t kw_args; diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c new file mode 100644 index 000000000..6451991e9 --- /dev/null +++ b/shared-bindings/bleio/Service.c @@ -0,0 +1,167 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Service` -- BLE service +//| ========================================================= +//| +//| Stores information about a BLE service and its characteristics. +//| + +//| .. class:: Service(uuid, secondary=False) +//| +//| Create a new Service object identified by the specified UUID. +//| To mark the service as secondary, pass `True` as :py:data:`secondary`. +//| +//| :param uuid: The uuid of the service +//| + +//| .. method:: add_characteristic(characteristic) +//| +//| Appends the :py:data:`characteristic` to the list of this service's characteristics. +//| +//| :param bleio.Characteristic characteristic: the characteristic to append +//| + +//| .. attribute:: characteristics +//| +//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only) +//| + +//| .. attribute:: uuid +//| +//| The UUID of this service. (read-only) +//| +STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Service(uuid: 0x"HEX2_FMT""HEX2_FMT")", + self->uuid->value[1], self->uuid->value[0]); +} + +STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); + self->base.type = &bleio_service_type; + self->periph = mp_const_none; + self->char_list = mp_obj_new_list(0, NULL); + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid, ARG_secondary }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + 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); + + self->is_secondary = args[ARG_secondary].u_bool; + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + if (uuid == MP_OBJ_NULL) { + return MP_OBJ_FROM_PTR(self); + } + + if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { + self->uuid = MP_OBJ_TO_PTR(uuid); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Invalid UUID parameter")); + } + + common_hal_bleio_service_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); + + characteristic->service_handle = self->handle; + + common_hal_bleio_service_add_characteristic(self, characteristic); + + mp_obj_list_append(self->char_list, characteristic); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_service_add_characteristic_obj, bleio_service_add_characteristic); + +STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->char_list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics); + +const mp_obj_property_t bleio_service_characteristics_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_characteristics_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_FROM_PTR(self->uuid); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid); + +const mp_obj_property_t bleio_service_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_add_characteristic), MP_ROM_PTR(&bleio_service_add_characteristic_obj) }, + { MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table); + +const mp_obj_type_t bleio_service_type = { + { &mp_type_type }, + .name = MP_QSTR_Service, + .print = bleio_service_print, + .make_new = bleio_service_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict +}; diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h new file mode 100644 index 000000000..6e3079cf9 --- /dev/null +++ b/shared-bindings/bleio/Service.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H + +#include "shared-module/bleio/Characteristic.h" +#include "shared-module/bleio/Service.h" + +const mp_obj_type_t bleio_service_type; + +extern void common_hal_bleio_service_construct(bleio_service_obj_t *self); +extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index f96abc449..9f5a8f8f2 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -25,7 +25,6 @@ * THE SOFTWARE. */ -#include "py/obj.h" #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/AddressType.h" @@ -34,6 +33,7 @@ #include "shared-bindings/bleio/Descriptor.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" +#include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/UUIDType.h" @@ -59,6 +59,7 @@ //| Descriptor //| ScanEntry //| Scanner +//| Service //| UUID //| UUIDType //| @@ -77,6 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, + { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, // Properties diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index aa313afd3..2347c9c30 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -27,11 +27,12 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H +#include "shared-module/bleio/Service.h" #include "common-hal/bleio/UUID.h" typedef struct { mp_obj_base_t base; - mp_obj_t service; + bleio_service_obj_t *service; uint16_t service_handle; bleio_uuid_obj_t *uuid; mp_obj_t value_data; diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h new file mode 100644 index 000000000..bd359a41d --- /dev/null +++ b/shared-module/bleio/Service.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H + +#include "modubluepy.h" +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + uint16_t handle; + bool is_secondary; + bleio_uuid_obj_t *uuid; + mp_obj_t periph; + mp_obj_t char_list; + uint16_t start_handle; + uint16_t end_handle; +} bleio_service_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H -- cgit v1.2.3 From 3bd65fbae5d0150139c0ffd4cf02f8c9f547bbf5 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 20:33:24 +0200 Subject: nrf: Move the Peripheral class to bleio as Device This was the last class from ubluepy and so that module is now gone. The Device class offers both Peripheral and Central functionality. See the inline docs for more info. --- ports/nrf/Makefile | 5 +- ports/nrf/common-hal/bleio/Characteristic.c | 6 +- ports/nrf/common-hal/bleio/Device.c | 166 ++++++++ ports/nrf/common-hal/bleio/Scanner.c | 3 +- ports/nrf/drivers/bluetooth/ble_drv.c | 396 +++++++++---------- ports/nrf/drivers/bluetooth/ble_drv.h | 36 +- ports/nrf/drivers/bluetooth/ble_uart.h | 1 - ports/nrf/modules/ubluepy/modubluepy.c | 48 --- ports/nrf/modules/ubluepy/modubluepy.h | 126 ------ ports/nrf/modules/ubluepy/ubluepy_peripheral.c | 507 ------------------------- ports/nrf/mpconfigport.h | 33 +- shared-bindings/bleio/Device.c | 348 +++++++++++++++++ shared-bindings/bleio/Device.h | 40 ++ shared-bindings/bleio/ScanEntry.c | 5 +- shared-bindings/bleio/ScanEntry.h | 11 +- shared-bindings/bleio/Service.c | 6 +- shared-bindings/bleio/__init__.c | 3 + shared-module/bleio/AdvertisementData.h | 9 + shared-module/bleio/Device.h | 45 +++ shared-module/bleio/ScanEntry.h | 40 ++ shared-module/bleio/Service.h | 3 +- 21 files changed, 860 insertions(+), 977 deletions(-) create mode 100644 ports/nrf/common-hal/bleio/Device.c delete mode 100644 ports/nrf/modules/ubluepy/modubluepy.c delete mode 100644 ports/nrf/modules/ubluepy/modubluepy.h delete mode 100644 ports/nrf/modules/ubluepy/ubluepy_peripheral.c create mode 100644 shared-bindings/bleio/Device.c create mode 100644 shared-bindings/bleio/Device.h create mode 100644 shared-module/bleio/Device.h create mode 100644 shared-module/bleio/ScanEntry.h diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 6112678f5..b059569ab 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -127,10 +127,6 @@ SRC_C += \ peripherals/nrf/timers.c \ supervisor/shared/memory.c -DRIVERS_SRC_C += $(addprefix modules/,\ - ubluepy/modubluepy.c \ - ubluepy/ubluepy_peripheral.c \ - ) SRC_COMMON_HAL += \ analogio/AnalogIn.c \ @@ -163,6 +159,7 @@ SRC_COMMON_HAL += \ bleio/Adapter.c \ bleio/Characteristic.c \ bleio/Descriptor.c \ + bleio/Device.c \ bleio/Scanner.c \ bleio/Service.c \ bleio/UUID.c diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 56afc52c5..938289f2d 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -26,6 +26,7 @@ #include "ble_drv.h" #include "shared-module/bleio/Characteristic.h" +#include "shared-module/bleio/Device.h" void data_callback(bleio_characteristic_obj_t *self, uint16_t length, uint8_t *data) { self->value_data = mp_obj_new_bytearray(length, data); @@ -36,10 +37,9 @@ void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self } void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(self->service->periph); - ubluepy_role_type_t role = peripheral->role; + const bleio_device_obj_t *device = MP_OBJ_TO_PTR(self->service->device); - if (role == UBLUEPY_ROLE_PERIPHERAL) { + if (device->is_peripheral) { // TODO: Add indications if (self->props.notify) { ble_drv_attr_s_notify(self, bufinfo); diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c new file mode 100644 index 000000000..ab2898e72 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Device.c @@ -0,0 +1,166 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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 + +#include "ble_drv.h" +#include "ble_gap.h" +#include "ble_gatt.h" +#include "ble_types.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +static volatile bool m_disc_evt_received; + +STATIC void gap_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { + if (event_id == BLE_GAP_EVT_CONNECTED) { + device->conn_handle = conn_handle; + } else if (event_id == BLE_GAP_EVT_DISCONNECTED) { + device->conn_handle = BLE_CONN_HANDLE_INVALID; + } +} + +STATIC void gatts_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { + +} + +STATIC void gattc_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { + m_disc_evt_received = true; +} + +STATIC void disc_add_service(bleio_device_obj_t *device, ble_drv_service_data_t * service_data) { + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (service_data->uuid_type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = service_data->uuid & 0xFF; + uuid->value[1] = service_data->uuid >> 8; + + service->char_list = mp_obj_new_list(0, NULL); + service->uuid = uuid; + service->device = device; + service->handle = service_data->start_handle; + service->start_handle = service_data->start_handle; + service->end_handle = service_data->end_handle; + + mp_obj_list_append(device->service_list, service); +} + +STATIC void disc_add_char(bleio_service_obj_t *service, ble_drv_char_data_t *chara_data) { + bleio_characteristic_obj_t *chara = m_new_obj(bleio_characteristic_obj_t); + chara->base.type = &bleio_characteristic_type; + + bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); + p_uuid->base.type = &bleio_uuid_type; + + chara->uuid = p_uuid; + + p_uuid->type = chara_data->uuid_type; + p_uuid->value[0] = chara_data->uuid & 0xFF; + p_uuid->value[1] = chara_data->uuid >> 8; + + // add characteristic specific data from discovery + chara->props.broadcast = chara_data->props.broadcast; + chara->props.indicate = chara_data->props.indicate; + chara->props.notify = chara_data->props.notify; + chara->props.read = chara_data->props.read; + chara->props.write = chara_data->props.write; + chara->props.write_wo_resp = chara_data->props.write_wo_resp; + chara->handle = chara_data->value_handle; + + chara->service_handle = service->handle; + chara->service = service; + + mp_obj_list_append(service->char_list, MP_OBJ_FROM_PTR(chara)); +} + + +void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) { + if (adv_data->connectable) { + ble_drv_gap_event_handler_set(device, gap_event_handler); + ble_drv_gatts_event_handler_set(device, gatts_event_handler); + } + + ble_drv_advertise_data(adv_data); +} + +void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { + (void)device; + + ble_drv_advertise_stop(); +} + +void common_hal_bleio_device_connect(bleio_device_obj_t *device) { + ble_drv_gap_event_handler_set(device, gap_event_handler); + + ble_drv_connect(device); + + while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { + run_background_tasks(); +// __asm volatile ("wfi"); + } + + ble_drv_gattc_event_handler_set(device, gattc_event_handler); + + // TODO: read name + + // find services + bool found_service = ble_drv_discover_services(device, BLE_GATT_HANDLE_START, disc_add_service); + while (found_service) { + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + const bleio_service_obj_t *service = service_list->items[service_list->len - 1]; + + found_service = ble_drv_discover_services(device, service->end_handle + 1, disc_add_service); + } + + // find characteristics in each service + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + for (size_t i = 0; i < service_list->len; ++i) { + bleio_service_obj_t *service = service_list->items[i]; + + bool found_char = ble_drv_discover_characteristic(device, service, service->start_handle, disc_add_char); + while (found_char) { + const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); + const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1]; + + const uint16_t next_handle = characteristic->handle + 1; + if (next_handle >= service->end_handle) { + break; + } + + found_char = ble_drv_discover_characteristic(device, service, next_handle, disc_add_char); + } + } +} + +void common_hal_bleio_device_disconnect(bleio_device_obj_t *device) { + ble_drv_disconnect(device); +} diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index ed1987144..0eb50a1f6 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -29,8 +29,9 @@ #include "ble_drv.h" #include "py/mphal.h" -#include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Scanner.h" +#include "shared-module/bleio/ScanEntry.h" STATIC void adv_event_handler(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data) { // TODO: Don't add new entry for each item, group by address and update diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index e421036ae..1ab1d9337 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +35,8 @@ #define NRF52 // Needed for SD132 v2 #endif +#include "shared-module/bleio/Device.h" +#include "py/objstr.h" #include "py/runtime.h" #include "supervisor/shared/translate.h" #include "ble_drv.h" @@ -41,15 +44,10 @@ #include "nrf_sdm.h" #include "nrfx_power.h" #include "ble_gap.h" +#include "ble_hci.h" #include "ble.h" // sd_ble_uuid_encode - -#define BLE_DRIVER_VERBOSE 0 -#if BLE_DRIVER_VERBOSE #define BLE_DRIVER_LOG printf -#else -#define BLE_DRIVER_LOG(...) -#endif #define BLE_ADV_LENGTH_FIELD_SIZE 1 #define BLE_ADV_AD_TYPE_FIELD_SIZE 1 @@ -61,8 +59,8 @@ #define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout. #define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS) -#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS) -#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS) +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) #define BLE_SLAVE_LATENCY 0 #define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) @@ -81,8 +79,8 @@ static volatile bool m_tx_in_progress; static ble_drv_gap_evt_callback_t gap_event_handler; static ble_drv_gatts_evt_callback_t gatts_event_handler; -static mp_obj_t mp_gap_observer; -static mp_obj_t mp_gatts_observer; +static bleio_device_obj_t *mp_gap_observer; +static bleio_device_obj_t *mp_gatts_observer; static volatile bool m_primary_service_found; static volatile bool m_characteristic_found; @@ -95,10 +93,11 @@ static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler; static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; static bleio_scanner_obj_t *mp_adv_observer; -static mp_obj_t mp_gattc_observer; -static mp_obj_t mp_gattc_disc_service_observer; -static mp_obj_t mp_gattc_disc_char_observer; +static bleio_device_obj_t *mp_gattc_observer; +static bleio_device_obj_t *mp_gattc_disc_service_observer; +static bleio_service_obj_t *mp_gattc_disc_char_observer; static bleio_characteristic_obj_t *mp_gattc_char_data_observer; +static bleio_address_obj_t *mp_connect_address; #if (BLUETOOTH_SD == 140) static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; @@ -123,18 +122,6 @@ uint32_t ble_drv_stack_enable(void) { m_adv_in_progress = false; m_tx_in_progress = false; -#if BLUETOOTH_LFCLK_RC - nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_RC, - .rc_ctiv = 16, - .rc_temp_ctiv = 2, -#if (BLE_API_VERSION == 4) - .accuracy = 0 -#else - .xtal_accuracy = 0 -#endif - }; -#else nrf_clock_lf_cfg_t clock_config = { .source = NRF_CLOCK_LF_SRC_XTAL, .rc_ctiv = 0, @@ -145,23 +132,22 @@ uint32_t ble_drv_stack_enable(void) { .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM #endif }; -#endif #if (BLUETOOTH_SD == 140) // The SD takes over the POWER IRQ and will fail if the IRQ is already in use nrfx_power_uninit(); #endif - uint32_t err_code = sd_softdevice_enable(&clock_config, - softdevice_assert_handler); - - BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code); + uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); + if (err_code != NRF_SUCCESS) + BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code); - err_code = sd_nvic_EnableIRQ(SWI2_EGU2_IRQn); - - BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code); + err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); + if (err_code != NRF_SUCCESS) + BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code); // Enable BLE stack. + uint32_t app_ram_start; #if (BLE_API_VERSION == 2) ble_enable_params_t ble_enable_params; memset(&ble_enable_params, 0x00, sizeof(ble_enable_params)); @@ -169,48 +155,17 @@ uint32_t ble_drv_stack_enable(void) { ble_enable_params.gatts_enable_params.service_changed = 0; ble_enable_params.gap_enable_params.periph_conn_count = 1; ble_enable_params.gap_enable_params.central_conn_count = 1; -#endif -#if (BLE_API_VERSION == 2) - uint32_t app_ram_start = 0x200039c0; + app_ram_start = 0x200039c0; err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); // 8K SD headroom from linker script. - BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); #else - uint32_t app_ram_start = 0x20004000; + app_ram_start = 0x20004000; err_code = sd_ble_enable(&app_ram_start); - BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); #endif - - BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code); - - // set up security mode - ble_gap_conn_params_t gap_conn_params; - ble_gap_conn_sec_mode_t sec_mode; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - - const char device_name[] = "micr"; - - if ((err_code = sd_ble_gap_device_name_set(&sec_mode, - (const uint8_t *)device_name, - strlen(device_name))) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Cannot apply GAP parameters."))); - } - - // set connection parameters - memset(&gap_conn_params, 0, sizeof(gap_conn_params)); - - gap_conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; - gap_conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; - gap_conn_params.slave_latency = BLE_SLAVE_LATENCY; - gap_conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; - - if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) { - - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Cannot set PPCP parameters."))); + if (err_code != NRF_SUCCESS) { + BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); + BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code); } return err_code; @@ -223,9 +178,10 @@ void ble_drv_stack_disable(void) { uint8_t ble_drv_stack_enabled(void) { uint8_t is_enabled; uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); - (void)err_code; - BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code); + if (err_code != NRF_SUCCESS) { + BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code); + } return is_enabled; } @@ -256,10 +212,10 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr) { memcpy(p_addr->addr, local_ble_addr.addr, 6); } -bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) { +bool ble_drv_uuid_add_vs(uint8_t *uuid, uint8_t *idx) { SD_TEST_OR_ENABLE(); - if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) { + if (sd_ble_uuid_vs_add((ble_uuid128_t const *)uuid, idx) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not add Vendor Specific 128-bit UUID."))); } @@ -284,9 +240,7 @@ void ble_drv_service_add(bleio_service_obj_t *service) { service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; } - if (sd_ble_gatts_service_add(service_type, - &uuid, - &service->handle) != 0) { + if (sd_ble_gatts_service_add(service_type, &uuid, &service->handle) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not add Service."))); } @@ -372,59 +326,66 @@ bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) { return true; } -bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { +// TODO: Replace with just bleio_device_obj_t + data +bool ble_drv_advertise_data(bleio_advertisement_data_t *adv_params) { SD_TEST_OR_ENABLE(); uint8_t byte_pos = 0; uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE]; - if (p_adv_params->device_name_len > 0) { - ble_gap_conn_sec_mode_t sec_mode; + GET_STR_DATA_LEN(adv_params->device_name, name_data, name_len); + if (name_len > 0) { + ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); if (sd_ble_gap_device_name_set(&sec_mode, - p_adv_params->p_device_name, - p_adv_params->device_name_len) != 0) { + name_data, + name_len) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not apply device name in the stack."))); } - BLE_DRIVER_LOG("Device name applied\n"); - - adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + p_adv_params->device_name_len); + adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + name_len); byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + + // TODO: Shorten if too long adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - memcpy(&adv_data[byte_pos], p_adv_params->p_device_name, p_adv_params->device_name_len); - // increment position counter to see if it fits, and in case more content should - // follow in this adv packet. - byte_pos += p_adv_params->device_name_len; + + memcpy(&adv_data[byte_pos], name_data, name_len); + + byte_pos += name_len; } - // Add FLAGS only if manually controlled data has not been used. - if (p_adv_params->data_len == 0) { - // set flags, default to disc mode + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(adv_params->data, &bufinfo, MP_BUFFER_WRITE); + + // set flags, default to disc mode + if (bufinfo.len == 0) { adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE); byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS; byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE; + adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; byte_pos += 1; } - if (p_adv_params->num_of_services > 0) { - + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(adv_params->services); + if (service_list->len > 0) { bool type_16bit_present = false; bool type_128bit_present = false; - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; - if (p_service->uuid->type == UUID_TYPE_16BIT) { + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->uuid->type == UUID_TYPE_16BIT) { type_16bit_present = true; } - if (p_service->uuid->type == UUID_TYPE_128BIT) { + if (service->uuid->type == UUID_TYPE_128BIT) { type_128bit_present = true; } } @@ -441,13 +402,17 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { uint8_t uuid_total_size = 0; uint8_t encoded_size = 0; - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->uuid->type != UUID_TYPE_16BIT) { + continue; + } ble_uuid_t uuid; - uuid.type = p_service->uuid->type; - uuid.uuid = p_service->uuid->value[0]; - uuid.uuid += p_service->uuid->value[1] << 8; + uuid.type = BLE_UUID_TYPE_BLE; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + // calculate total size of uuids if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, @@ -460,19 +425,8 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { translate("Can encode UUID into the advertisement packet."))); } - BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); - for (uint8_t j = 0; j < encoded_size; j++) { - BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]); - } - BLE_DRIVER_LOG("\n"); - uuid_total_size += encoded_size; // size of entry byte_pos += encoded_size; // relative to adv data packet - BLE_DRIVER_LOG("ADV: uuid size: %u, type: %u, uuid: %x%x, vs_idx: %u\n", - encoded_size, p_service->p_uuid->type, - p_service->p_uuid->value[1], - p_service->p_uuid->value[0], - p_service->p_uuid->uuid_vs_idx); } adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); @@ -490,13 +444,16 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { uint8_t uuid_total_size = 0; uint8_t encoded_size = 0; - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - bleio_service_obj_t * p_service = (bleio_service_obj_t *)p_adv_params->p_services[i]; + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->uuid->type != UUID_TYPE_128BIT) { + continue; + } ble_uuid_t uuid; - uuid.type = p_service->uuid->uuid_vs_idx; - uuid.uuid = p_service->uuid->value[0]; - uuid.uuid += p_service->uuid->value[1] << 8; + uuid.type = service->uuid->uuid_vs_idx; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); // calculate total size of uuids if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { @@ -510,51 +467,37 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { translate("Can encode UUID into the advertisement packet."))); } - BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); - for (uint8_t j = 0; j < encoded_size; j++) { - BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]); - } - BLE_DRIVER_LOG("\n"); - uuid_total_size += encoded_size; // size of entry byte_pos += encoded_size; // relative to adv data packet - BLE_DRIVER_LOG("ADV: uuid size: %u, type: %x%x, uuid: %u, vs_idx: %u\n", - encoded_size, p_service->p_uuid->type, - p_service->p_uuid->value[1], - p_service->p_uuid->value[0], - p_service->p_uuid->uuid_vs_idx); } adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); } } - if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) { - if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) { + if (bufinfo.len > 0) { + if (byte_pos + bufinfo.len > BLE_GAP_ADV_MAX_SIZE) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not fit data into the advertisement packet."))); } - memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len); - byte_pos += p_adv_params->data_len; + memcpy(adv_data, bufinfo.buf, bufinfo.len); + byte_pos += bufinfo.len; } - // scan response data not set uint32_t err_code; #if (BLUETOOTH_SD == 132) if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); } - BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos); #endif static ble_gap_adv_params_t m_adv_params; // initialize advertising params memset(&m_adv_params, 0, sizeof(m_adv_params)); - if (p_adv_params->connectable) { + if (adv_params->connectable) { #if (BLUETOOTH_SD == 140) m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; #else @@ -643,8 +586,8 @@ void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, ui } void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); - uint16_t conn_handle = peripheral->conn_handle; + bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); + uint16_t conn_handle = device->conn_handle; ble_gatts_value_t gatts_value; memset(&gatts_value, 0, sizeof(gatts_value)); @@ -662,8 +605,8 @@ void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_ } void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); - uint16_t conn_handle = peripheral->conn_handle; + bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); + uint16_t conn_handle = device->conn_handle; ble_gatts_hvx_params_t hvx_params; uint16_t hvx_len = bufinfo->len; @@ -676,7 +619,9 @@ void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer hvx_params.p_data = bufinfo->buf; while (m_tx_in_progress) { - ; +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } m_tx_in_progress = true; @@ -687,50 +632,49 @@ void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer } } -void ble_drv_gap_event_handler_set(mp_obj_t obj, ble_drv_gap_evt_callback_t evt_handler) { - mp_gap_observer = obj; +void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler) { + mp_gap_observer = device; gap_event_handler = evt_handler; } -void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler) { - mp_gatts_observer = obj; +void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler) { + mp_gatts_observer = device; gatts_event_handler = evt_handler; } -void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler) { - mp_gattc_observer = obj; +void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler) { + mp_gattc_observer = device; gattc_event_handler = evt_handler; } -void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler) { - mp_adv_observer = self; +void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *device, ble_drv_adv_evt_callback_t evt_handler) { + mp_adv_observer = device; adv_event_handler = evt_handler; } - void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) { bleio_service_obj_t *service = characteristic->service; - ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(service->periph); + bleio_device_obj_t *device = MP_OBJ_TO_PTR(service->device); mp_gattc_char_data_observer = characteristic; gattc_char_data_handle = cb; - const uint32_t err_code = sd_ble_gattc_read(peripheral->conn_handle, - characteristic->handle, - 0); + const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); if (err_code != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); } while (gattc_char_data_handle != NULL) { - ; +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } } void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - ubluepy_peripheral_obj_t *peripheral = MP_OBJ_TO_PTR(characteristic->service->periph); - uint16_t conn_handle = peripheral->conn_handle; + bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); + uint16_t conn_handle = device->conn_handle; ble_gattc_write_params_t write_params; write_params.write_op = BLE_GATT_OP_WRITE_REQ; @@ -753,10 +697,13 @@ void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_ translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); } - while (m_write_done != true) { - ; + while (m_write_done != true) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } } + void ble_drv_scan_start(uint16_t interval, uint16_t window) { SD_TEST_OR_ENABLE(); @@ -798,109 +745,108 @@ void ble_drv_scan_stop(void) { sd_ble_gap_scan_stop(); } -void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) { - SD_TEST_OR_ENABLE(); +STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data) { + if (memcmp(data->p_peer_addr, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) { + ble_drv_adv_report_handler_set(NULL, NULL); - ble_gap_scan_params_t scan_params; - scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.timeout = 0; // Infinite + ble_gap_scan_params_t scan_params; + memset(&scan_params, 0, sizeof(scan_params)); - ble_gap_addr_t addr; - memset(&addr, 0, sizeof(addr)); + scan_params.active = 1; + scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); + scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); + scan_params.timeout = 0; - addr.addr_type = addr_type; - memcpy(addr.addr, p_addr, 6); + ble_gap_addr_t addr; + memset(&addr, 0, sizeof(addr)); - BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n", - addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5], addr.addr_type); + addr.addr_type = data->addr_type; + memcpy(addr.addr, data->p_peer_addr, BLEIO_ADDRESS_BYTES); - ble_gap_conn_params_t conn_params; + BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n", + addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], addr.addr_type); + + ble_gap_conn_params_t conn_params = { + .min_conn_interval = BLE_MIN_CONN_INTERVAL, + .max_conn_interval = BLE_MAX_CONN_INTERVAL, + .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, + .slave_latency = BLE_SLAVE_LATENCY, + }; + + uint32_t err_code; + #if (BLE_API_VERSION == 2) + if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) { + #else + if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) { + #endif + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Can not connect. status: 0x" HEX2_FMT, (uint16_t)err_code)); + } + } +} -// (void)sd_ble_gap_ppcp_get(&conn_params); +void ble_drv_connect(bleio_device_obj_t *device) { + SD_TEST_OR_ENABLE(); - // set connection parameters - memset(&conn_params, 0, sizeof(conn_params)); + mp_connect_address = &device->address; + ble_drv_adv_report_handler_set(NULL, ble_drv_connect_scan_callback); - conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; - conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; - conn_params.slave_latency = BLE_SLAVE_LATENCY; - conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; + ble_drv_scan_start(100, 100); +} - uint32_t err_code; -#if (BLE_API_VERSION == 2) - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) { -#else - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) { -#endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not connect. status: 0x%02x"), (uint16_t)err_code)); - } +void ble_drv_disconnect(bleio_device_obj_t *device) { + sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } -bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) { - BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n", - conn_handle); +bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) { + BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle); - mp_gattc_disc_service_observer = obj; + mp_gattc_disc_service_observer = device; disc_add_service_handler = cb; m_primary_service_found = false; uint32_t err_code; - err_code = sd_ble_gattc_primary_services_discover(conn_handle, - start_handle, - NULL); + err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); if (err_code != 0) { return false; } // busy loop until last service has been iterated while (disc_add_service_handler != NULL) { - ; +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } - if (m_primary_service_found) { - return true; - } else { - return false; - } + return m_primary_service_found; } -bool ble_drv_discover_characteristic(mp_obj_t obj, - uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - ble_drv_disc_add_char_callback_t cb) { - BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", - conn_handle); +bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb) { + BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle); - mp_gattc_disc_char_observer = obj; + mp_gattc_disc_char_observer = service; disc_add_char_handler = cb; ble_gattc_handle_range_t handle_range; handle_range.start_handle = start_handle; - handle_range.end_handle = end_handle; + handle_range.end_handle = service->end_handle; m_characteristic_found = false; - uint32_t err_code; - err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); + uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range); if (err_code != 0) { return false; } // busy loop until last service has been iterated while (disc_add_char_handler != NULL) { - ; +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } - if (m_characteristic_found) { - return true; - } else { - return false; - } + return m_characteristic_found; } void ble_drv_discover_descriptors(void) { @@ -908,12 +854,8 @@ void ble_drv_discover_descriptors(void) { } static void ble_evt_handler(ble_evt_t * p_ble_evt) { -// S132 event ranges. -// Common 0x01 -> 0x0F -// GAP 0x10 -> 0x2F -// GATTC 0x30 -> 0x4F -// GATTS 0x50 -> 0x6F -// L2CAP 0x70 -> 0x8F + printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); + switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: BLE_DRIVER_LOG("GAP CONNECT\n"); @@ -1104,7 +1046,7 @@ static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attr static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)] __attribute__ ((aligned (4))); #endif -void SWI2_EGU2_IRQHandler(void) { +void SD_EVT_IRQHandler(void) { uint32_t evt_id; uint32_t err_code; do { diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index 8c6bd6ce3..e5282db73 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -32,12 +32,12 @@ #include #include +#include "shared-module/bleio/AdvertisementData.h" #include "shared-module/bleio/Characteristic.h" +#include "shared-module/bleio/Device.h" #include "shared-module/bleio/Scanner.h" #include "shared-module/bleio/Service.h" -#include "modubluepy.h" - typedef struct { uint8_t addr[6]; uint8_t addr_type; @@ -75,12 +75,12 @@ typedef struct { uint16_t value_handle; } ble_drv_char_data_t; -typedef void (*ble_drv_gap_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gatts_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gattc_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data); -typedef void (*ble_drv_disc_add_service_callback_t)(mp_obj_t self, ble_drv_service_data_t * p_service_data); -typedef void (*ble_drv_disc_add_char_callback_t)(mp_obj_t self, ble_drv_char_data_t * p_desc_data); +typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); +typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); +typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); +typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data); +typedef void (*ble_drv_disc_add_service_callback_t)(bleio_device_obj_t *device, ble_drv_service_data_t * p_service_data); +typedef void (*ble_drv_disc_add_char_callback_t)(bleio_service_obj_t *service, ble_drv_char_data_t * p_desc_data); typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); uint32_t ble_drv_stack_enable(void); @@ -97,15 +97,15 @@ void ble_drv_service_add(bleio_service_obj_t *service); bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic); -bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params); +bool ble_drv_advertise_data(bleio_advertisement_data_t *p_adv_params); void ble_drv_advertise_stop(void); -void ble_drv_gap_event_handler_set(mp_obj_t obs, ble_drv_gap_evt_callback_t evt_handler); +void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler); -void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler); +void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler); -void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler); +void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler); void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); @@ -125,15 +125,13 @@ void ble_drv_scan_stop(void); void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler); -void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type); +void ble_drv_connect(bleio_device_obj_t *device); + +void ble_drv_disconnect(bleio_device_obj_t *device); -bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb); +bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb); -bool ble_drv_discover_characteristic(mp_obj_t obj, - uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - ble_drv_disc_add_char_callback_t cb); +bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb); void ble_drv_discover_descriptors(void); diff --git a/ports/nrf/drivers/bluetooth/ble_uart.h b/ports/nrf/drivers/bluetooth/ble_uart.h index e67176a26..336624cd3 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.h +++ b/ports/nrf/drivers/bluetooth/ble_uart.h @@ -29,7 +29,6 @@ #if BLUETOOTH_SD -#include "modubluepy.h" #include "ble_drv.h" void ble_uart_init0(void); diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c deleted file mode 100644 index f8266a82d..000000000 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 "py/obj.h" - -#if MICROPY_PY_UBLUEPY - -extern const mp_obj_type_t ubluepy_peripheral_type; -extern const mp_obj_type_t ubluepy_service_type; - -STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table); - -const mp_obj_module_t mp_module_ubluepy = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&mp_module_ubluepy_globals, -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h deleted file mode 100644 index e301f0476..000000000 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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. - */ - -#ifndef UBLUEPY_H__ -#define UBLUEPY_H__ - -/* Examples: - -Advertisment: - -from ubluepy import Peripheral -p = Peripheral() -p.advertise(device_name="MicroPython") - -DB setup: - -from ubluepy import Service, Characteristic, UUID, Peripheral, constants -from pyb import LED - -def event_handler(id, handle, data): - print("BLE event:", id, "handle:", handle) - print(data) - - if id == constants.EVT_GAP_CONNECTED: - # connected - LED(2).on() - elif id == constants.EVT_GAP_DISCONNECTED: - # disconnect - LED(2).off() - elif id == 80: - print("id 80, data:", data) - -# u0 = UUID("0x180D") # HRM service -# u1 = UUID("0x2A37") # HRM measurement - -u0 = UUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e") -u1 = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e") -u2 = UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e") -s = Service(u0) -c0 = Characteristic(u1, props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP) -c1 = Characteristic(u2, props = Characteristic.PROP_NOTIFY, attrs = Characteristic.ATTR_CCCD) -s.addCharacteristic(c0) -s.addCharacteristic(c1) -p = Peripheral() -p.addService(s) -p.setConnectionHandler(event_handler) -p.advertise(device_name="micr", services=[s]) - -*/ - -#include "common-hal/bleio/UUID.h" -#include "py/obj.h" - -extern const mp_obj_type_t ubluepy_peripheral_type; - -typedef enum { - UBLUEPY_ADDR_TYPE_PUBLIC = 0, - UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1, - UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2, - UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3, -} ubluepy_addr_type_t; - -typedef enum { - UBLUEPY_ROLE_PERIPHERAL, - UBLUEPY_ROLE_CENTRAL -} ubluepy_role_type_t; - -typedef struct _ubluepy_peripheral_obj_t { - mp_obj_base_t base; - ubluepy_role_type_t role; - volatile uint16_t conn_handle; - mp_obj_t delegate; - mp_obj_t notif_handler; - mp_obj_t conn_handler; - mp_obj_t service_list; -} ubluepy_peripheral_obj_t; - -typedef struct _ubluepy_advertise_data_t { - uint8_t * p_device_name; - uint8_t device_name_len; - mp_obj_t * p_services; - uint8_t num_of_services; - uint8_t * p_data; - uint8_t data_len; - bool connectable; -} ubluepy_advertise_data_t; - -typedef enum _ubluepy_prop_t { - UBLUEPY_PROP_BROADCAST = 0x01, - UBLUEPY_PROP_READ = 0x02, - UBLUEPY_PROP_WRITE_WO_RESP = 0x04, - UBLUEPY_PROP_WRITE = 0x08, - UBLUEPY_PROP_NOTIFY = 0x10, - UBLUEPY_PROP_INDICATE = 0x20, - UBLUEPY_PROP_AUTH_SIGNED_WR = 0x40, -} ubluepy_prop_t; - -typedef enum _ubluepy_attr_t { - UBLUEPY_ATTR_CCCD = 0x01, - UBLUEPY_ATTR_SCCD = 0x02, -} ubluepy_attr_t; - -#endif // UBLUEPY_H__ diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c deleted file mode 100644 index 3b1a0d279..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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 -#include "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" - -#if MICROPY_PY_UBLUEPY - -#include "ble_drv.h" -#include "common-hal/bleio/UUID.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" - -STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_peripheral_obj_t * self = (ubluepy_peripheral_obj_t *)o; - (void)self; - mp_printf(print, "Peripheral(conn_handle: " HEX2_FMT ")", - self->conn_handle); -} - -STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (event_id == 16) { // connect event - self->conn_handle = conn_handle; - } else if (event_id == 17) { // disconnect event - self->conn_handle = 0xFFFF; // invalid connection handle - } - - if (self->conn_handler != mp_const_none) { - mp_obj_t args[3]; - mp_uint_t num_of_args = 3; - args[0] = MP_OBJ_NEW_SMALL_INT(event_id); - args[1] = MP_OBJ_NEW_SMALL_INT(conn_handle); - if (data != NULL) { - args[2] = mp_obj_new_bytearray_by_ref(length, data); - } else { - args[2] = mp_const_none; - } - - // for now hard-code all events to conn_handler - mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args); - } - - (void)self; -} - -STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (self->conn_handler != mp_const_none) { - mp_obj_t args[3]; - mp_uint_t num_of_args = 3; - args[0] = MP_OBJ_NEW_SMALL_INT(event_id); - args[1] = MP_OBJ_NEW_SMALL_INT(attr_handle); - if (data != NULL) { - args[2] = mp_obj_new_bytearray_by_ref(length, data); - } else { - args[2] = mp_const_none; - } - - // for now hard-code all events to conn_handler - mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args); - } - -} - -#if MICROPY_PY_UBLUEPY_CENTRAL - -static volatile bool m_disc_evt_received; - -STATIC void gattc_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - (void)self; - m_disc_evt_received = true; -} -#endif - -STATIC mp_obj_t ubluepy_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { - ARG_NEW_DEVICE_ADDR, - ARG_NEW_ADDR_TYPE - }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_DEVICE_ADDR, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { ARG_NEW_ADDR_TYPE, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_peripheral_obj_t *s = m_new_obj(ubluepy_peripheral_obj_t); - s->base.type = type; - - s->delegate = mp_const_none; - s->conn_handler = mp_const_none; - s->notif_handler = mp_const_none; - s->conn_handle = 0xFFFF; - - s->service_list = mp_obj_new_list(0, NULL); - - return MP_OBJ_FROM_PTR(s); -} - -/// \method withDelegate(DefaultDelegate) -/// Set delegate instance for handling Bluetooth LE events. -/// -STATIC mp_obj_t peripheral_with_delegate(mp_obj_t self_in, mp_obj_t delegate) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->delegate = delegate; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_with_delegate_obj, peripheral_with_delegate); - -/// \method setNotificationHandler(func) -/// Set handler for Bluetooth LE notification events. -/// -STATIC mp_obj_t peripheral_set_notif_handler(mp_obj_t self_in, mp_obj_t func) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->notif_handler = func; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_notif_handler_obj, peripheral_set_notif_handler); - -/// \method setConnectionHandler(func) -/// Set handler for Bluetooth LE connection events. -/// -STATIC mp_obj_t peripheral_set_conn_handler(mp_obj_t self_in, mp_obj_t func) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->conn_handler = func; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_conn_handler_obj, peripheral_set_conn_handler); - -#if MICROPY_PY_UBLUEPY_PERIPHERAL - -/// \method advertise(device_name, [service=[service1, service2, ...]], [data=bytearray], [connectable=True]) -/// Start advertising. Connectable advertisement type by default. -/// -STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_device_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_services, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - - self->role = UBLUEPY_ROLE_PERIPHERAL; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t device_name_obj = args[0].u_obj; - mp_obj_t service_obj = args[1].u_obj; - mp_obj_t data_obj = args[2].u_obj; - mp_obj_t connectable_obj = args[3].u_obj; - - ubluepy_advertise_data_t adv_data; - memset(&adv_data, 0, sizeof(ubluepy_advertise_data_t)); - - if (device_name_obj != mp_const_none && MP_OBJ_IS_STR(device_name_obj)) { - GET_STR_DATA_LEN(device_name_obj, str_data, str_len); - - adv_data.p_device_name = (uint8_t *)str_data; - adv_data.device_name_len = str_len; - } - - if (service_obj != mp_const_none) { - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(service_obj, &num_services, &services); - - if (num_services > 0) { - adv_data.p_services = services; - adv_data.num_of_services = num_services; - } - } - - if (data_obj != mp_const_none) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); - - if (bufinfo.len > 0) { - adv_data.p_data = bufinfo.buf; - adv_data.data_len = bufinfo.len; - } - } - - adv_data.connectable = true; - if (connectable_obj != mp_const_none && !(mp_obj_is_true(connectable_obj))) { - adv_data.connectable = false; - } else { - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler); - ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(self), gatts_event_handler); - } - - (void)ble_drv_advertise_data(&adv_data); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_advertise_obj, 0, peripheral_advertise); - -/// \method advertise_stop() -/// Stop advertisement if any onging advertisement. -/// -STATIC mp_obj_t peripheral_advertise_stop(mp_obj_t self_in) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - ble_drv_advertise_stop(); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_advertise_stop_obj, peripheral_advertise_stop); - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL - -/// \method disconnect() -/// disconnect connection. -/// -STATIC mp_obj_t peripheral_disconnect(mp_obj_t self_in) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_disconnect_obj, peripheral_disconnect); - -/// \method addService(Service) -/// Add service to the Peripheral. -/// -STATIC mp_obj_t peripheral_add_service(mp_obj_t self_in, mp_obj_t service) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service); - - p_service->periph = self_in; - - mp_obj_list_append(self->service_list, service); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_add_service_obj, peripheral_add_service); - -/// \method getServices() -/// Return list with all service registered in the Peripheral. -/// -STATIC mp_obj_t peripheral_get_services(mp_obj_t self_in) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - - return self->service_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_get_services_obj, peripheral_get_services); - -#if MICROPY_PY_UBLUEPY_CENTRAL - -void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_data) { - bleio_service_obj_t * p_service = m_new_obj(bleio_service_obj_t); - p_service->base.type = &bleio_service_type; - - bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); - p_uuid->base.type = &bleio_uuid_type; - - p_service->uuid = p_uuid; - - p_uuid->type = p_service_data->uuid_type; - p_uuid->value[0] = p_service_data->uuid & 0xFF; - p_uuid->value[1] = p_service_data->uuid >> 8; - - p_service->handle = p_service_data->start_handle; - p_service->start_handle = p_service_data->start_handle; - p_service->end_handle = p_service_data->end_handle; - - p_service->char_list = mp_obj_new_list(0, NULL); - - peripheral_add_service(self, MP_OBJ_FROM_PTR(p_service)); -} - -void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data) { - bleio_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in); - bleio_characteristic_obj_t * p_char = m_new_obj(bleio_characteristic_obj_t); - p_char->base.type = &bleio_characteristic_type; - - bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); - p_uuid->base.type = &bleio_uuid_type; - - p_char->uuid = p_uuid; - - p_uuid->type = p_desc_data->uuid_type; - p_uuid->value[0] = p_desc_data->uuid & 0xFF; - p_uuid->value[1] = p_desc_data->uuid >> 8; - - // add characteristic specific data from discovery - p_char->props.broadcast = p_desc_data->props.broadcast; - p_char->props.indicate = p_desc_data->props.indicate; - p_char->props.notify = p_desc_data->props.notify; - p_char->props.read = p_desc_data->props.read; - p_char->props.write = p_desc_data->props.write; - p_char->props.write_wo_resp = p_desc_data->props.write_wo_resp; - p_char->handle = p_desc_data->value_handle; - - // equivalent to ubluepy_service.c - service_add_characteristic() - // except the registration of the characteristic towards the bluetooth stack - p_char->service_handle = p_service->handle; - p_char->service = p_service; - - mp_obj_list_append(p_service->char_list, MP_OBJ_FROM_PTR(p_char)); -} - -/// \method connect(device_address [, addr_type=ADDR_TYPE_PUBLIC]) -/// Connect to device peripheral with the given device address. -/// addr_type can be either ADDR_TYPE_PUBLIC (default) or -/// ADDR_TYPE_RANDOM_STATIC. -/// -STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t dev_addr = pos_args[1]; - - self->role = UBLUEPY_ROLE_CENTRAL; - - static const mp_arg_t allowed_args[] = { - { MP_QSTR_addr_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UBLUEPY_ADDR_TYPE_PUBLIC } }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - uint8_t addr_type = args[0].u_int; - - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler); - - if (MP_OBJ_IS_STR(dev_addr)) { - GET_STR_DATA_LEN(dev_addr, str_data, str_len); - if (str_len == 17) { // Example "11:22:33:aa:bb:cc" - - uint8_t * p_addr = m_new(uint8_t, 6); - - p_addr[0] = unichar_xdigit_value(str_data[16]); - p_addr[0] += unichar_xdigit_value(str_data[15]) << 4; - p_addr[1] = unichar_xdigit_value(str_data[13]); - p_addr[1] += unichar_xdigit_value(str_data[12]) << 4; - p_addr[2] = unichar_xdigit_value(str_data[10]); - p_addr[2] += unichar_xdigit_value(str_data[9]) << 4; - p_addr[3] = unichar_xdigit_value(str_data[7]); - p_addr[3] += unichar_xdigit_value(str_data[6]) << 4; - p_addr[4] = unichar_xdigit_value(str_data[4]); - p_addr[4] += unichar_xdigit_value(str_data[3]) << 4; - p_addr[5] = unichar_xdigit_value(str_data[1]); - p_addr[5] += unichar_xdigit_value(str_data[0]) << 4; - - ble_drv_connect(p_addr, addr_type); - - m_del(uint8_t, p_addr, 6); - } - } - - // block until connected - while (self->conn_handle == 0xFFFF) { - ; - } - - ble_drv_gattc_event_handler_set(MP_OBJ_FROM_PTR(self), gattc_event_handler); - - bool service_disc_retval = ble_drv_discover_services(self, self->conn_handle, 0x0001, disc_add_service); - - // continue discovery of primary services ... - while (service_disc_retval) { - // locate the last added service - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(self->service_list, &num_services, &services); - - bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[num_services - 1]; - - service_disc_retval = ble_drv_discover_services(self, - self->conn_handle, - p_service->end_handle + 1, - disc_add_service); - } - - // For each service perform a characteristic discovery - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(self->service_list, &num_services, &services); - - for (uint16_t s = 0; s < num_services; s++) { - bleio_service_obj_t * p_service = (bleio_service_obj_t *)services[s]; - bool char_disc_retval = ble_drv_discover_characteristic(p_service, - self->conn_handle, - p_service->start_handle, - p_service->end_handle, - disc_add_char); - // continue discovery of characteristics ... - while (char_disc_retval) { - mp_obj_t * characteristics = NULL; - mp_uint_t num_chars; - mp_obj_get_array(p_service->char_list, &num_chars, &characteristics); - - bleio_characteristic_obj_t * p_char = (bleio_characteristic_obj_t *)characteristics[num_chars - 1]; - uint16_t next_handle = p_char->handle + 1; - if ((next_handle) < p_service->end_handle) { - char_disc_retval = ble_drv_discover_characteristic(p_service, - self->conn_handle, - next_handle, - p_service->end_handle, - disc_add_char); - } else { - break; - } - } - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_connect_obj, 2, peripheral_connect); - -#endif - -STATIC const mp_rom_map_elem_t ubluepy_peripheral_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_withDelegate), MP_ROM_PTR(&ubluepy_peripheral_with_delegate_obj) }, - { MP_ROM_QSTR(MP_QSTR_setNotificationHandler), MP_ROM_PTR(&ubluepy_peripheral_set_notif_handler_obj) }, - { MP_ROM_QSTR(MP_QSTR_setConnectionHandler), MP_ROM_PTR(&ubluepy_peripheral_set_conn_handler_obj) }, - { MP_ROM_QSTR(MP_QSTR_getServices), MP_ROM_PTR(&ubluepy_peripheral_get_services_obj) }, -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ubluepy_peripheral_connect_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_getServiceByUUID), MP_ROM_PTR(&ubluepy_peripheral_get_service_by_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_peripheral_get_chars_obj) }, - { MP_ROM_QSTR(MP_QSTR_getDescriptors), MP_ROM_PTR(&ubluepy_peripheral_get_descs_obj) }, - { MP_ROM_QSTR(MP_QSTR_waitForNotifications), MP_ROM_PTR(&ubluepy_peripheral_wait_for_notif_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) }, -#endif // 0 -#endif // MICROPY_PY_UBLUEPY_CENTRAL -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) }, - { MP_ROM_QSTR(MP_QSTR_advertise_stop), MP_ROM_PTR(&ubluepy_peripheral_advertise_stop_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_addService), MP_ROM_PTR(&ubluepy_peripheral_add_service_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_add_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_addDescriptor), MP_ROM_PTR(&ubluepy_peripheral_add_desc_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) }, -#endif -#endif -#if MICROPY_PY_UBLUEPY_BROADCASTER - { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) }, -#endif -#if MICROPY_PY_UBLUEPY_OBSERVER - // Nothing yet. -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_peripheral_locals_dict, ubluepy_peripheral_locals_dict_table); - -const mp_obj_type_t ubluepy_peripheral_type = { - { &mp_type_type }, - .name = MP_QSTR_Peripheral, - .print = ubluepy_peripheral_print, - .make_new = ubluepy_peripheral_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index b710808b9..62a041ae9 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -129,21 +129,15 @@ #define CIRCUITPY_GAMEPAD_TICKS 0x1f #if BLUETOOTH_SD -#define MICROPY_PY_BLEIO (1) -#define MICROPY_PY_BLE_NUS (0) -#define MICROPY_PY_UBLUEPY (1) -#define MICROPY_PY_UBLUEPY_PERIPHERAL (1) -#define MICROPY_PY_UBLUEPY_CENTRAL (1) -#define BLUETOOTH_WEBBLUETOOTH_REPL (0) -#endif - -#ifndef MICROPY_PY_BLEIO -#define MICROPY_PY_BLEIO (0) + #define MICROPY_PY_BLEIO (1) + #define MICROPY_PY_BLE_NUS (0) + #define BLUETOOTH_WEBBLUETOOTH_REPL (0) +#else + #ifndef MICROPY_PY_BLEIO + #define MICROPY_PY_BLEIO (0) + #endif #endif -#ifndef MICROPY_PY_UBLUEPY -#define MICROPY_PY_UBLUEPY (0) -#endif // type definitions for the specific machine @@ -184,16 +178,8 @@ extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t usb_hid_module; extern const struct _mp_obj_module_t bleio_module; -extern const struct _mp_obj_module_t mp_module_ubluepy; - -#if MICROPY_PY_UBLUEPY -#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) }, -#else -#define UBLUEPY_MODULE -#endif - #if MICROPY_PY_BLEIO -#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) }, +#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) }, #else #define BLEIO_MODULE #endif @@ -221,8 +207,7 @@ extern const struct _mp_obj_module_t mp_module_ubluepy; { MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ USBHID_MODULE \ - BLEIO_MODULE \ - UBLUEPY_MODULE \ + BLEIO_MODULE // extra built in names to add to the global namespace #define MICROPY_PORT_BUILTINS \ diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c new file mode 100644 index 000000000..15ebd51ed --- /dev/null +++ b/shared-bindings/bleio/Device.c @@ -0,0 +1,348 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "ble_drv.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/AddressType.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/Device.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Device` -- BLE device +//| ========================================================= +//| +//| Provides access a to BLE device, either in a Peripheral or Central role. +//| When a device is created without any parameter passed to the constructor, +//| it will be set to the Peripheral role. If a address is passed, the device +//| will be a Central. For a Peripheral you can set the `name`, add services +//| via `add_service` and then start and stop advertising via `start_advertising` +//| and `stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect` +//| to the device, once a connection is established, the device's services can +//| be accessed using `services`. +//| +//| Usage:: +//| +//| import bleio +//| +//| # Peripheral +//| periph = bleio.Device() +//| +//| serv = bleio.Service(bleio.UUID(0x180f)) +//| p.add_service(serv) +//| +//| chara = bleio.Characteristic(bleio.UUID(0x2919)) +//| chara.read = True +//| chara.notify = True +//| serv.add_characteristic(chara) +//| +//| periph.start_advertising() +//| +//| # Central +//| scanner = bleio.Scanner() +//| entries = scanner.scan(2500) +//| +//| my_entry = None +//| for entry in entries: +//| if entry.name is not None and entry.name == 'MyDevice': +//| my_entry = entry +//| break +//| +//| central = bleio.Device(my_entry.address) +//| central.connect() +//| + +//| .. class:: Device(address=None) +//| +//| Create a new Device object. If the `address` parameter is not `None`, +//| the role is set to Central, otherwise it's set to Peripheral. +//| +//| :param bleio.Address address: The address of the device to connect to +//| + +//| .. attribute:: name +//| +//| For the Peripheral role, this property can be used to read and write the device's name. +//| For the Central role, this property will equal the name of the remote device, if one was +//| advertised by the device. In the Central role this property is read-only. +//| + +//| .. attribute:: services +//| +//| A `list` of `bleio.Service` that are offered by this device. (read-only) +//| For a Peripheral device, this list will contain services added using `add_service`, +//| for a Central, this list will be empty until a connection is established, at which point +//| it will be filled with the remote device's services. +//| + +//| .. method:: add_service(service) +//| +//| Appends the :py:data:`service` to the list of this devices's services. +//| This method can only be called for Peripheral devices. +//| +//| :param bleio.Service service: the service to append +//| + +//| .. method:: connect() +//| +//| Attempts a connection to the remote device. If the connection is successful, +//| the device's services are available via `services`. +//| This method can only be called for Central devices. +//| + +//| .. method:: disconnect() +//| +//| Disconnects from the remote device. +//| This method can only be called for Central devices. +//| + +//| .. method:: start_advertising(connectable=True) +//| +//| Starts advertising the device. The device's name and +//| services are put into the advertisement packets. +//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device. +//| This method can only be called for Peripheral devices. +//| + +//| .. method:: stop_advertising() +//| +//| Disconnects from the remote device. +//| This method can only be called for Peripheral devices. +//| +static const char default_name[] = "CIRCUITPY"; + +STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central"); +} + +STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t); + self->base.type = &bleio_device_type; + self->service_list = mp_obj_new_list(0, NULL); + self->notif_handler = mp_const_none; + self->conn_handler = mp_const_none; + self->conn_handle = 0xFFFF; + self->is_peripheral = true; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + //TODO: Add ScanEntry + enum { ARG_address }; + static const mp_arg_t allowed_args[] = { + { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + 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); + + const mp_obj_t address_obj = args[ARG_address].u_obj; + + if (address_obj != mp_const_none) { + bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj); + + self->is_peripheral = false; + self->address.type = address->type; + memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES); + } else { + self->name = mp_obj_new_str(default_name, strlen(default_name), false); + common_hal_bleio_adapter_get_address(&self->address); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Can't add services in Central mode")); + } + + service->device = self_in; + + mp_obj_list_append(self->service_list, service); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service); + +STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Can't connect in Peripheral mode")); + } + + common_hal_bleio_device_connect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect); + +STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_device_disconnect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect); + +STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->name; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name); + +static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Can't change the name in Central mode")); + } + + self->name = value; + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name); + +const mp_obj_property_t bleio_device_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_device_get_name_obj, + (mp_obj_t)&bleio_device_set_name_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Can't advertise in Central mode")); + } + + enum { ARG_connectable }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // TODO: data + bleio_advertisement_data_t adv_data = { + .device_name = self->name, + .services = mp_obj_new_list(0, NULL), + .data = mp_obj_new_bytearray(0, NULL), + .connectable = args[ARG_connectable].u_bool + }; + + mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + for (size_t i = 0; i < service_list->len; ++i) { + bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + if (!service->is_secondary) { + mp_obj_list_append(adv_data.services, service_list->items[i]); + } + } + + common_hal_bleio_device_start_advertising(self, &adv_data); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising); + +STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Can't advertise in Central mode")); + } + + common_hal_bleio_device_stop_advertising(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising); + +STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->service_list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services); + +const mp_obj_property_t bleio_device_services_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_device_get_services_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table); + +const mp_obj_type_t bleio_device_type = { + { &mp_type_type }, + .name = MP_QSTR_Device, + .print = bleio_device_print, + .make_new = bleio_device_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict +}; diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Device.h new file mode 100644 index 000000000..d099e5c43 --- /dev/null +++ b/shared-bindings/bleio/Device.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H + +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/Device.h" + +extern const mp_obj_type_t bleio_device_type; + +extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data); +extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device); +extern void common_hal_bleio_device_connect(bleio_device_obj_t *device); +extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c index e38a08909..2eed24cd8 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/bleio/ScanEntry.c @@ -32,9 +32,10 @@ #include "py/objstr.h" #include "py/objtuple.h" #include "shared-bindings/bleio/Address.h" -#include "shared-module/bleio/AdvertisementData.h" -#include "shared-bindings/bleio/UUID.h" #include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/ScanEntry.h" //| .. currentmodule:: bleio //| diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h index 4a201124e..2b44ba3f4 100644 --- a/shared-bindings/bleio/ScanEntry.h +++ b/shared-bindings/bleio/ScanEntry.h @@ -28,16 +28,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H -#include "shared-module/bleio/Address.h" -#include "py/objtype.h" - -typedef struct { - mp_obj_base_t base; - bleio_address_obj_t address; - bool connectable; - int8_t rssi; - mp_obj_t data; -} bleio_scanentry_obj_t; +#include "py/obj.h" extern const mp_obj_type_t bleio_scanentry_type; diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 6451991e9..5b61a2966 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -73,7 +73,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 1, 1, true); bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); self->base.type = &bleio_service_type; - self->periph = mp_const_none; + self->device = mp_const_none; self->char_list = mp_obj_new_list(0, NULL); mp_map_t kw_args; @@ -81,7 +81,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, enum { ARG_uuid, ARG_secondary }; static const mp_arg_t allowed_args[] = { - { ARG_uuid, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_uuid, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; @@ -92,7 +92,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t uuid = args[ARG_uuid].u_obj; - if (uuid == MP_OBJ_NULL) { + if (uuid == mp_const_none) { return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 9f5a8f8f2..98099422c 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -31,6 +31,7 @@ #include "shared-bindings/bleio/AdvertisementData.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/Device.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-bindings/bleio/Service.h" @@ -57,6 +58,7 @@ //| Adapter //| Characteristic //| Descriptor +//| Device //| ScanEntry //| Scanner //| Service @@ -76,6 +78,7 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&bleio_device_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h index 2a9addf57..738d53b23 100644 --- a/shared-module/bleio/AdvertisementData.h +++ b/shared-module/bleio/AdvertisementData.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#include "py/obj.h" + // Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile enum { AdFlags = 0x01, @@ -73,4 +75,11 @@ enum { AdManufacturerSpecificData = 0xFF, }; +typedef struct { + mp_obj_t device_name; + mp_obj_t services; + mp_obj_t data; + bool connectable; +} bleio_advertisement_data_t; + #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H diff --git a/shared-module/bleio/Device.h b/shared-module/bleio/Device.h new file mode 100644 index 000000000..afbd8f063 --- /dev/null +++ b/shared-module/bleio/Device.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H + +#include + +#include "shared-module/bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + bool is_peripheral; + mp_obj_t name; + bleio_address_obj_t address; + uint16_t conn_handle; + mp_obj_t service_list; + mp_obj_t notif_handler; + mp_obj_t conn_handler; +} bleio_device_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/bleio/ScanEntry.h new file mode 100644 index 000000000..2f01669e2 --- /dev/null +++ b/shared-module/bleio/ScanEntry.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H + +#include "shared-module/bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + bleio_address_obj_t address; + bool connectable; + int8_t rssi; + mp_obj_t data; +} bleio_scanentry_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h index bd359a41d..1e3f09119 100644 --- a/shared-module/bleio/Service.h +++ b/shared-module/bleio/Service.h @@ -27,7 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H -#include "modubluepy.h" #include "common-hal/bleio/UUID.h" typedef struct { @@ -35,7 +34,7 @@ typedef struct { uint16_t handle; bool is_secondary; bleio_uuid_obj_t *uuid; - mp_obj_t periph; + mp_obj_t device; mp_obj_t char_list; uint16_t start_handle; uint16_t end_handle; -- cgit v1.2.3 From 5412bf66c351f2a1a94ef9e0bc12b62be15b76d0 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 20:35:24 +0200 Subject: bleio: Improve type documentation --- shared-bindings/bleio/Characteristic.c | 2 +- shared-bindings/bleio/Scanner.c | 3 ++- shared-bindings/bleio/Service.c | 3 ++- shared-bindings/bleio/UUID.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 97aed679e..905babecb 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -43,7 +43,7 @@ //| //| Create a new Characteristic object identified by the specified UUID. //| -//| :param uuid: The uuid of the characteristic +//| :param bleio.UUID uuid: The uuid of the characteristic //| //| .. attribute:: broadcast diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c index 00e29d9d5..5d19778f6 100644 --- a/shared-bindings/bleio/Scanner.c +++ b/shared-bindings/bleio/Scanner.c @@ -65,8 +65,9 @@ //| .. method:: scan(timeout) //| -//| Performs a BLE scan lasting :py:data:`timeout` ms. +//| Performs a BLE scan. //| +//| :param int timeout: the scan timeout in ms //| :returns: advertising packets found //| :rtype: list of :py:class:`bleio.ScanEntry` //| diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 5b61a2966..338269a5f 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -43,7 +43,8 @@ //| Create a new Service object identified by the specified UUID. //| To mark the service as secondary, pass `True` as :py:data:`secondary`. //| -//| :param uuid: The uuid of the service +//| :param bleio.UUID uuid: The uuid of the service +//| :param bool secondary: If the service is a secondary one //| //| .. method:: add_characteristic(characteristic) diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 0523e918f..93a2051c1 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -89,7 +89,7 @@ enum { //| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit //| - another UUID object //| -//| :param uuid: The uuid to encapsulate +//| :param int/str uuid: The uuid to encapsulate //| //| .. attribute:: type -- cgit v1.2.3 From 4b344812bfdd1d5139b132e6d09dc6f2f5314fa4 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 20:40:33 +0200 Subject: nrf: Remove the ble drv specific address struct --- ports/nrf/common-hal/bleio/Adapter.c | 6 +----- ports/nrf/drivers/bluetooth/ble_drv.c | 6 +++--- ports/nrf/drivers/bluetooth/ble_drv.h | 7 +------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index f4c35ac69..e264b9d49 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -51,9 +51,5 @@ bool common_hal_bleio_adapter_get_enabled(void) { } void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { - ble_drv_addr_t drv_addr; - ble_drv_address_get(&drv_addr); - - address->type = drv_addr.addr_type; - memcpy(address->value, drv_addr.addr, BLEIO_ADDRESS_BYTES); + ble_drv_address_get(address); } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 1ab1d9337..2d0aa7cfa 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -186,7 +186,7 @@ uint8_t ble_drv_stack_enabled(void) { return is_enabled; } -void ble_drv_address_get(ble_drv_addr_t * p_addr) { +void ble_drv_address_get(bleio_address_obj_t *address) { SD_TEST_OR_ENABLE(); ble_gap_addr_t local_ble_addr; @@ -208,8 +208,8 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr) { local_ble_addr.addr[5], local_ble_addr.addr[4], local_ble_addr.addr[3], \ local_ble_addr.addr[2], local_ble_addr.addr[1], local_ble_addr.addr[0]); - p_addr->addr_type = local_ble_addr.addr_type; - memcpy(p_addr->addr, local_ble_addr.addr, 6); + address->type = local_ble_addr.addr_type; + memcpy(address->value, local_ble_addr.addr, BLEIO_ADDRESS_BYTES); } bool ble_drv_uuid_add_vs(uint8_t *uuid, uint8_t *idx) { diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index e5282db73..c48cb6c21 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -38,11 +38,6 @@ #include "shared-module/bleio/Scanner.h" #include "shared-module/bleio/Service.h" -typedef struct { - uint8_t addr[6]; - uint8_t addr_type; -} ble_drv_addr_t; - typedef struct { uint8_t * p_peer_addr; uint8_t addr_type; @@ -89,7 +84,7 @@ void ble_drv_stack_disable(void); uint8_t ble_drv_stack_enabled(void); -void ble_drv_address_get(ble_drv_addr_t * p_addr); +void ble_drv_address_get(bleio_address_obj_t *address); bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx); -- cgit v1.2.3 From 3df7dea2cc8c9e3327a4915f717f94154ee4a71f Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 20:59:32 +0200 Subject: nrf: Remove the ble drv specific advertisement data struct --- ports/nrf/common-hal/bleio/Scanner.c | 12 ++------ ports/nrf/drivers/bluetooth/ble_drv.c | 55 +++++++++++++++++------------------ ports/nrf/drivers/bluetooth/ble_drv.h | 13 ++------- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index 0eb50a1f6..150c417a3 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -33,18 +33,10 @@ #include "shared-bindings/bleio/Scanner.h" #include "shared-module/bleio/ScanEntry.h" -STATIC void adv_event_handler(bleio_scanner_obj_t *self, ble_drv_adv_data_t *data) { +STATIC void adv_event_handler(bleio_scanner_obj_t *self, bleio_scanentry_obj_t *entry) { // TODO: Don't add new entry for each item, group by address and update - bleio_scanentry_obj_t *item = m_new_obj(bleio_scanentry_obj_t); - item->base.type = &bleio_scanentry_type; - item->rssi = data->rssi; - item->data = mp_obj_new_bytearray(data->data_len, data->p_data); - - item->address.type = data->addr_type; - memcpy(item->address.value, data->p_peer_addr, BLEIO_ADDRESS_BYTES); - - mp_obj_list_append(self->adv_reports, item); + mp_obj_list_append(self->adv_reports, entry); ble_drv_scan_continue(); } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 2d0aa7cfa..7bcd9353e 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -35,6 +35,7 @@ #define NRF52 // Needed for SD132 v2 #endif +#include "shared-bindings/bleio/ScanEntry.h" #include "shared-module/bleio/Device.h" #include "py/objstr.h" #include "py/runtime.h" @@ -745,8 +746,8 @@ void ble_drv_scan_stop(void) { sd_ble_gap_scan_stop(); } -STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data) { - if (memcmp(data->p_peer_addr, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) { +STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry) { + if (memcmp(entry->address.value, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) { ble_drv_adv_report_handler_set(NULL, NULL); ble_gap_scan_params_t scan_params; @@ -760,8 +761,8 @@ STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, ble_drv_ ble_gap_addr_t addr; memset(&addr, 0, sizeof(addr)); - addr.addr_type = data->addr_type; - memcpy(addr.addr, data->p_peer_addr, BLEIO_ADDRESS_BYTES); + addr.addr_type = entry->address.type; + memcpy(addr.addr, entry->address.value, BLEIO_ADDRESS_BYTES); BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n", addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], addr.addr_type); @@ -853,6 +854,26 @@ void ble_drv_discover_descriptors(void) { } +STATIC void on_adv_report(ble_gap_evt_adv_report_t *report) { + bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); + entry->base.type = &bleio_scanentry_type; + + entry->rssi = report->rssi; + + entry->address.type = report->peer_addr.addr_type; + memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); + +#if (BLUETOOTH_SD == 140) + entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data); +#else + entry->data = mp_obj_new_bytearray(report->dlen, report->data); +#endif + + if (adv_event_handler != NULL) { + adv_event_handler(mp_adv_observer, entry); + } +} + static void ble_evt_handler(ble_evt_t * p_ble_evt) { printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); @@ -920,31 +941,7 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) { break; case BLE_GAP_EVT_ADV_REPORT: - BLE_DRIVER_LOG("BLE EVT ADV REPORT\n"); - ble_drv_adv_data_t adv_data = { - .p_peer_addr = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr, - .addr_type = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr_type, -#if (BLUETOOTH_SD == 140) - .is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.type.scannable, -#else - .is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.scan_rsp, -#endif - .rssi = p_ble_evt->evt.gap_evt.params.adv_report.rssi, -#if (BLUETOOTH_SD == 140) - .data_len = p_ble_evt->evt.gap_evt.params.adv_report.data.len, - .p_data = p_ble_evt->evt.gap_evt.params.adv_report.data.p_data, -#else - .data_len = p_ble_evt->evt.gap_evt.params.adv_report.dlen, - .p_data = p_ble_evt->evt.gap_evt.params.adv_report.data, -#endif -#if (BLUETOOTH_SD == 132) - .adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type -#endif - }; - - if (adv_event_handler != NULL) { - adv_event_handler(mp_adv_observer, &adv_data); - } + on_adv_report(&p_ble_evt->evt.gap_evt.params.adv_report); break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index c48cb6c21..c3abf980b 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -35,19 +35,10 @@ #include "shared-module/bleio/AdvertisementData.h" #include "shared-module/bleio/Characteristic.h" #include "shared-module/bleio/Device.h" +#include "shared-module/bleio/ScanEntry.h" #include "shared-module/bleio/Scanner.h" #include "shared-module/bleio/Service.h" -typedef struct { - uint8_t * p_peer_addr; - uint8_t addr_type; - bool is_scan_resp; - int8_t rssi; - uint8_t data_len; - uint8_t * p_data; - uint8_t adv_type; -} ble_drv_adv_data_t; - typedef struct { uint16_t uuid; uint8_t uuid_type; @@ -73,7 +64,7 @@ typedef struct { typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, ble_drv_adv_data_t *data); +typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry); typedef void (*ble_drv_disc_add_service_callback_t)(bleio_device_obj_t *device, ble_drv_service_data_t * p_service_data); typedef void (*ble_drv_disc_add_char_callback_t)(bleio_service_obj_t *service, ble_drv_char_data_t * p_desc_data); typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); -- cgit v1.2.3 From 98aa8c5923ae335b5d5143398bb5db2449940ad9 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 22:10:16 +0200 Subject: nrf: Remove the ble drv specific service struct --- ports/nrf/common-hal/bleio/Device.c | 30 +++----------- ports/nrf/drivers/bluetooth/ble_drv.c | 77 +++++++++++++++++++---------------- ports/nrf/drivers/bluetooth/ble_drv.h | 10 +---- 3 files changed, 48 insertions(+), 69 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index ab2898e72..04151431c 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -54,26 +54,6 @@ STATIC void gattc_event_handler(bleio_device_obj_t *device, uint16_t event_id, u m_disc_evt_received = true; } -STATIC void disc_add_service(bleio_device_obj_t *device, ble_drv_service_data_t * service_data) { - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - service->base.type = &bleio_service_type; - - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - uuid->type = (service_data->uuid_type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = service_data->uuid & 0xFF; - uuid->value[1] = service_data->uuid >> 8; - - service->char_list = mp_obj_new_list(0, NULL); - service->uuid = uuid; - service->device = device; - service->handle = service_data->start_handle; - service->start_handle = service_data->start_handle; - service->end_handle = service_data->end_handle; - - mp_obj_list_append(device->service_list, service); -} - STATIC void disc_add_char(bleio_service_obj_t *service, ble_drv_char_data_t *chara_data) { bleio_characteristic_obj_t *chara = m_new_obj(bleio_characteristic_obj_t); chara->base.type = &bleio_characteristic_type; @@ -102,7 +82,6 @@ STATIC void disc_add_char(bleio_service_obj_t *service, ble_drv_char_data_t *cha mp_obj_list_append(service->char_list, MP_OBJ_FROM_PTR(chara)); } - void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) { if (adv_data->connectable) { ble_drv_gap_event_handler_set(device, gap_event_handler); @@ -124,8 +103,9 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { ble_drv_connect(device); while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { - run_background_tasks(); -// __asm volatile ("wfi"); +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } ble_drv_gattc_event_handler_set(device, gattc_event_handler); @@ -133,12 +113,12 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { // TODO: read name // find services - bool found_service = ble_drv_discover_services(device, BLE_GATT_HANDLE_START, disc_add_service); + bool found_service = ble_drv_discover_services(device, BLE_GATT_HANDLE_START); while (found_service) { const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); const bleio_service_obj_t *service = service_list->items[service_list->len - 1]; - found_service = ble_drv_discover_services(device, service->end_handle + 1, disc_add_service); + found_service = ble_drv_discover_services(device, service->end_handle + 1); } // find characteristics in each service diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 7bcd9353e..797d1a573 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -36,6 +36,8 @@ #endif #include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" #include "shared-module/bleio/Device.h" #include "py/objstr.h" #include "py/runtime.h" @@ -89,7 +91,6 @@ static volatile bool m_write_done; static volatile ble_drv_adv_evt_callback_t adv_event_handler; static volatile ble_drv_gattc_evt_callback_t gattc_event_handler; -static volatile ble_drv_disc_add_service_callback_t disc_add_service_handler; static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler; static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; @@ -799,22 +800,18 @@ void ble_drv_disconnect(bleio_device_obj_t *device) { sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } -bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) { - BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle); - +bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle) { mp_gattc_disc_service_observer = device; - disc_add_service_handler = cb; m_primary_service_found = false; - uint32_t err_code; - err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); - if (err_code != 0) { - return false; + uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to discover serivices. status: 0x" HEX2_FMT, (uint16_t)err_code)); } - // busy loop until last service has been iterated - while (disc_add_service_handler != NULL) { + while (mp_gattc_disc_service_observer != NULL) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif @@ -840,7 +837,6 @@ bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_o return false; } - // busy loop until last service has been iterated while (disc_add_char_handler != NULL) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP @@ -874,7 +870,39 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report) { } } -static void ble_evt_handler(ble_evt_t * p_ble_evt) { +STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response) { + BLE_DRIVER_LOG(">>> service count: %d\n", response->count); + + for (size_t i = 0; i < response->count; ++i) { + const ble_gattc_service_t *gattc_service = &response->services[i]; + + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; + service->char_list = mp_obj_new_list(0, NULL); + service->start_handle = gattc_service->handle_range.start_handle; + service->end_handle = gattc_service->handle_range.end_handle; + service->handle = gattc_service->handle_range.start_handle; + service->device = mp_gattc_disc_service_observer; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_service->uuid.uuid & 0xFF; + uuid->value[1] = gattc_service->uuid.uuid >> 8; + service->uuid = uuid; + + mp_obj_list_append(mp_gattc_disc_service_observer->service_list, service); + } + + if (response->count > 0) { + m_primary_service_found = true; + } + + // mark end of service discovery + mp_gattc_disc_service_observer = NULL; +} + +STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); switch (p_ble_evt->header.evt_id) { @@ -952,28 +980,7 @@ static void ble_evt_handler(ble_evt_t * p_ble_evt) { break; case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - BLE_DRIVER_LOG("BLE EVT PRIMARY SERVICE DISCOVERY RESPONSE\n"); - BLE_DRIVER_LOG(">>> service count: %d\n", p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count); - - for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count; i++) { - ble_gattc_service_t * p_service = &p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i]; - - ble_drv_service_data_t service; - service.uuid_type = p_service->uuid.type; - service.uuid = p_service->uuid.uuid; - service.start_handle = p_service->handle_range.start_handle; - service.end_handle = p_service->handle_range.end_handle; - - disc_add_service_handler(mp_gattc_disc_service_observer, &service); - } - - if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) { - m_primary_service_found = true; - } - - // mark end of service discovery - disc_add_service_handler = NULL; - + on_primary_srv_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp); break; case BLE_GATTC_EVT_CHAR_DISC_RSP: diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index c3abf980b..9ac70f97c 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -39,13 +39,6 @@ #include "shared-module/bleio/Scanner.h" #include "shared-module/bleio/Service.h" -typedef struct { - uint16_t uuid; - uint8_t uuid_type; - uint16_t start_handle; - uint16_t end_handle; -} ble_drv_service_data_t; - typedef struct { uint16_t uuid; uint8_t uuid_type; @@ -65,7 +58,6 @@ typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry); -typedef void (*ble_drv_disc_add_service_callback_t)(bleio_device_obj_t *device, ble_drv_service_data_t * p_service_data); typedef void (*ble_drv_disc_add_char_callback_t)(bleio_service_obj_t *service, ble_drv_char_data_t * p_desc_data); typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); @@ -115,7 +107,7 @@ void ble_drv_connect(bleio_device_obj_t *device); void ble_drv_disconnect(bleio_device_obj_t *device); -bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb); +bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle); bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb); -- cgit v1.2.3 From 6545aa99a9d86f4e93a89bee75ecd04e17bed3d2 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 22:59:18 +0200 Subject: nrf: Remove the ble drv specific characteristic struct --- ports/nrf/common-hal/bleio/Device.c | 32 +-------------- ports/nrf/drivers/bluetooth/ble_drv.c | 75 ++++++++++++++++++++--------------- ports/nrf/drivers/bluetooth/ble_drv.h | 18 +-------- 3 files changed, 45 insertions(+), 80 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 04151431c..848e60c57 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -54,34 +54,6 @@ STATIC void gattc_event_handler(bleio_device_obj_t *device, uint16_t event_id, u m_disc_evt_received = true; } -STATIC void disc_add_char(bleio_service_obj_t *service, ble_drv_char_data_t *chara_data) { - bleio_characteristic_obj_t *chara = m_new_obj(bleio_characteristic_obj_t); - chara->base.type = &bleio_characteristic_type; - - bleio_uuid_obj_t * p_uuid = m_new_obj(bleio_uuid_obj_t); - p_uuid->base.type = &bleio_uuid_type; - - chara->uuid = p_uuid; - - p_uuid->type = chara_data->uuid_type; - p_uuid->value[0] = chara_data->uuid & 0xFF; - p_uuid->value[1] = chara_data->uuid >> 8; - - // add characteristic specific data from discovery - chara->props.broadcast = chara_data->props.broadcast; - chara->props.indicate = chara_data->props.indicate; - chara->props.notify = chara_data->props.notify; - chara->props.read = chara_data->props.read; - chara->props.write = chara_data->props.write; - chara->props.write_wo_resp = chara_data->props.write_wo_resp; - chara->handle = chara_data->value_handle; - - chara->service_handle = service->handle; - chara->service = service; - - mp_obj_list_append(service->char_list, MP_OBJ_FROM_PTR(chara)); -} - void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) { if (adv_data->connectable) { ble_drv_gap_event_handler_set(device, gap_event_handler); @@ -126,7 +98,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { for (size_t i = 0; i < service_list->len; ++i) { bleio_service_obj_t *service = service_list->items[i]; - bool found_char = ble_drv_discover_characteristic(device, service, service->start_handle, disc_add_char); + bool found_char = ble_drv_discover_characteristic(device, service, service->start_handle); while (found_char) { const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1]; @@ -136,7 +108,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { break; } - found_char = ble_drv_discover_characteristic(device, service, next_handle, disc_add_char); + found_char = ble_drv_discover_characteristic(device, service, next_handle); } } } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 797d1a573..e911adc93 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -35,6 +35,7 @@ #define NRF52 // Needed for SD132 v2 #endif +#include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" @@ -91,7 +92,6 @@ static volatile bool m_write_done; static volatile ble_drv_adv_evt_callback_t adv_event_handler; static volatile ble_drv_gattc_evt_callback_t gattc_event_handler; -static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler; static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; static bleio_scanner_obj_t *mp_adv_observer; @@ -820,11 +820,10 @@ bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle return m_primary_service_found; } -bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb) { +bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) { BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle); mp_gattc_disc_char_observer = service; - disc_add_char_handler = cb; ble_gattc_handle_range_t handle_range; handle_range.start_handle = start_handle; @@ -837,7 +836,7 @@ bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_o return false; } - while (disc_add_char_handler != NULL) { + while (mp_gattc_disc_char_observer != NULL) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif @@ -902,6 +901,44 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res mp_gattc_disc_service_observer = NULL; } +STATIC void on_characteristic_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response) { + BLE_DRIVER_LOG(">>> characteristic count: %d\n", response->count); + + for (size_t i = 0; i < response->count; ++i) { + const ble_gattc_char_t *gattc_char = &response->chars[i]; + + bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); + characteristic->base.type = &bleio_characteristic_type; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_char->uuid.uuid & 0xFF; + uuid->value[1] = gattc_char->uuid.uuid >> 8; + characteristic->uuid = uuid; + + characteristic->props.broadcast = gattc_char->char_props.broadcast; + characteristic->props.indicate = gattc_char->char_props.indicate; + characteristic->props.notify = gattc_char->char_props.notify; + characteristic->props.read = gattc_char->char_props.read; + characteristic->props.write = gattc_char->char_props.write; + characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; + characteristic->handle = gattc_char->handle_value; + + characteristic->service_handle = mp_gattc_disc_char_observer->handle; + characteristic->service = mp_gattc_disc_char_observer; + + mp_obj_list_append(mp_gattc_disc_char_observer->char_list, MP_OBJ_FROM_PTR(characteristic)); + } + + if (response->count > 0) { + m_characteristic_found = true; + } + + // mark end of characteristic discovery + mp_gattc_disc_char_observer = NULL; +} + STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); @@ -984,35 +1021,7 @@ STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { break; case BLE_GATTC_EVT_CHAR_DISC_RSP: - BLE_DRIVER_LOG("BLE EVT CHAR DISCOVERY RESPONSE\n"); - BLE_DRIVER_LOG(">>> characteristic count: %d\n", p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count); - - for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) { - ble_gattc_char_t * p_char = &p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]; - - ble_drv_char_data_t char_data; - char_data.uuid_type = p_char->uuid.type; - char_data.uuid = p_char->uuid.uuid; - char_data.decl_handle = p_char->handle_decl; - char_data.value_handle = p_char->handle_value; - - char_data.props.broadcast = p_char->char_props.broadcast; - char_data.props.read = p_char->char_props.read; - char_data.props.write_wo_resp = p_char->char_props.write_wo_resp; - char_data.props.write = p_char->char_props.write; - char_data.props.notify = p_char->char_props.notify; - char_data.props.indicate = p_char->char_props.indicate; - - disc_add_char_handler(mp_gattc_disc_char_observer, &char_data); - } - - if (p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count > 0) { - m_characteristic_found = true; - } - - // mark end of characteristic discovery - disc_add_char_handler = NULL; - + on_characteristic_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp); break; case BLE_GATTC_EVT_READ_RSP: diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index 9ac70f97c..e0f95eefe 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -39,26 +39,10 @@ #include "shared-module/bleio/Scanner.h" #include "shared-module/bleio/Service.h" -typedef struct { - uint16_t uuid; - uint8_t uuid_type; - struct { - bool broadcast : 1; - bool read : 1; - bool write_wo_resp : 1; - bool write : 1; - bool notify : 1; - bool indicate : 1; - } props; - uint16_t decl_handle; - uint16_t value_handle; -} ble_drv_char_data_t; - typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry); -typedef void (*ble_drv_disc_add_char_callback_t)(bleio_service_obj_t *service, ble_drv_char_data_t * p_desc_data); typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); uint32_t ble_drv_stack_enable(void); @@ -109,7 +93,7 @@ void ble_drv_disconnect(bleio_device_obj_t *device); bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle); -bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle, ble_drv_disc_add_char_callback_t cb); +bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle); void ble_drv_discover_descriptors(void); -- cgit v1.2.3 From a126897f524588de21a8acdb603c53d073c376a0 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 23:41:01 +0200 Subject: bleio: Fix incorrect role detection --- shared-bindings/bleio/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 15ebd51ed..386261683 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -299,7 +299,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_d STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) { bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->is_peripheral) { + if (!self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Can't advertise in Central mode")); } -- cgit v1.2.3 From 77eeecbfd92ab24504f0081630a3c3633c5be18b Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 19 Jul 2018 23:51:34 +0200 Subject: nrf: BLE driver cleanup --- ports/nrf/common-hal/bleio/Adapter.c | 18 +++-- ports/nrf/common-hal/bleio/Characteristic.c | 6 +- ports/nrf/common-hal/bleio/Device.c | 8 --- ports/nrf/drivers/bluetooth/ble_drv.c | 100 ++++++++++------------------ ports/nrf/drivers/bluetooth/ble_drv.h | 19 ++---- 5 files changed, 53 insertions(+), 98 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index e264b9d49..bee9bd395 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -31,18 +31,22 @@ #include "ble_drv.h" #include "nrfx.h" #include "nrf_error.h" +#include "nrf_sdm.h" +#include "py/nlr.h" #include "shared-module/bleio/Address.h" void common_hal_bleio_adapter_set_enabled(bool enabled) { - if (enabled) { - const uint32_t err = ble_drv_stack_enable(); - if (err != NRF_SUCCESS) { - NRFX_ASSERT(err); - } + uint32_t err_code; - printf("SoftDevice enabled\n"); + if (enabled) { + err_code = ble_drv_stack_enable(); } else { - ble_drv_stack_disable(); + err_code = sd_softdevice_disable(); + } + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to change softdevice status, error: 0x%08lX", err_code)); } } diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 938289f2d..35b4f5e24 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -28,12 +28,8 @@ #include "shared-module/bleio/Characteristic.h" #include "shared-module/bleio/Device.h" -void data_callback(bleio_characteristic_obj_t *self, uint16_t length, uint8_t *data) { - self->value_data = mp_obj_new_bytearray(length, data); -} - void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { - ble_drv_attr_c_read(self, data_callback); + ble_drv_attr_c_read(self); } void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 848e60c57..9e7b382dd 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -36,8 +36,6 @@ #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -static volatile bool m_disc_evt_received; - STATIC void gap_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { if (event_id == BLE_GAP_EVT_CONNECTED) { device->conn_handle = conn_handle; @@ -50,10 +48,6 @@ STATIC void gatts_event_handler(bleio_device_obj_t *device, uint16_t event_id, u } -STATIC void gattc_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - m_disc_evt_received = true; -} - void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) { if (adv_data->connectable) { ble_drv_gap_event_handler_set(device, gap_event_handler); @@ -80,8 +74,6 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { #endif } - ble_drv_gattc_event_handler_set(device, gattc_event_handler); - // TODO: read name // find services diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index e911adc93..6d32ff6f9 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -44,12 +44,14 @@ #include "py/runtime.h" #include "supervisor/shared/translate.h" #include "ble_drv.h" -#include "mpconfigport.h" +#include "nrf_nvic.h" #include "nrf_sdm.h" #include "nrfx_power.h" -#include "ble_gap.h" -#include "ble_hci.h" -#include "ble.h" // sd_ble_uuid_encode +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/UUID.h" #define BLE_DRIVER_LOG printf @@ -60,8 +62,6 @@ #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) #define UNIT_0_625_MS (625) #define UNIT_10_MS (10000) -#define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout. -#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS) #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) #define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) @@ -77,29 +77,24 @@ if (ble_drv_stack_enabled() == 0) { \ (void)ble_drv_stack_enable(); \ } -static volatile bool m_adv_in_progress; -static volatile bool m_tx_in_progress; - -static ble_drv_gap_evt_callback_t gap_event_handler; -static ble_drv_gatts_evt_callback_t gatts_event_handler; +static ble_drv_adv_evt_callback_t adv_event_handler; +static ble_drv_gatts_evt_callback_t gatts_event_handler; +static ble_drv_gap_evt_callback_t gap_event_handler; -static bleio_device_obj_t *mp_gap_observer; +static bleio_characteristic_obj_t *mp_gattc_char_data_observer; +static bleio_device_obj_t *mp_gattc_disc_service_observer; +static bleio_service_obj_t *mp_gattc_disc_char_observer; +static bleio_address_obj_t *mp_connect_address; static bleio_device_obj_t *mp_gatts_observer; +static bleio_scanner_obj_t *mp_adv_observer; +static bleio_device_obj_t *mp_gap_observer; static volatile bool m_primary_service_found; static volatile bool m_characteristic_found; +static volatile bool m_tx_in_progress; static volatile bool m_write_done; -static volatile ble_drv_adv_evt_callback_t adv_event_handler; -static volatile ble_drv_gattc_evt_callback_t gattc_event_handler; -static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; - -static bleio_scanner_obj_t *mp_adv_observer; -static bleio_device_obj_t *mp_gattc_observer; -static bleio_device_obj_t *mp_gattc_disc_service_observer; -static bleio_service_obj_t *mp_gattc_disc_char_observer; -static bleio_characteristic_obj_t *mp_gattc_char_data_observer; -static bleio_address_obj_t *mp_connect_address; +nrf_nvic_state_t nrf_nvic_state = { 0 }; #if (BLUETOOTH_SD == 140) static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; @@ -112,18 +107,11 @@ static ble_data_t m_scan_buffer = }; #endif -#include "nrf_nvic.h" - -nrf_nvic_state_t nrf_nvic_state = {0}; - void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!"); } uint32_t ble_drv_stack_enable(void) { - m_adv_in_progress = false; - m_tx_in_progress = false; - nrf_clock_lf_cfg_t clock_config = { .source = NRF_CLOCK_LF_SRC_XTAL, .rc_ctiv = 0, @@ -173,10 +161,6 @@ uint32_t ble_drv_stack_enable(void) { return err_code; } -void ble_drv_stack_disable(void) { - sd_softdevice_disable(); -} - uint8_t ble_drv_stack_enabled(void) { uint8_t is_enabled; uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); @@ -549,24 +533,25 @@ bool ble_drv_advertise_data(bleio_advertisement_data_t *adv_params) { translate("Can not start advertisement. status: 0x%02x"), (uint16_t)err_code)); } - m_adv_in_progress = true; - return true; } void ble_drv_advertise_stop(void) { - if (m_adv_in_progress == true) { - uint32_t err_code; + uint32_t err_code; + #if (BLUETOOTH_SD == 140) - if ((err_code = sd_ble_gap_adv_stop(m_adv_handle)) != 0) { + if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + return; + + err_code = sd_ble_gap_adv_stop(m_adv_handle); #else - if ((err_code = sd_ble_gap_adv_stop()) != 0) { + err_code = sd_ble_gap_adv_stop(); #endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code)); - } + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code)); } - m_adv_in_progress = false; } void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { @@ -644,22 +629,16 @@ void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_e gatts_event_handler = evt_handler; } -void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler) { - mp_gattc_observer = device; - gattc_event_handler = evt_handler; -} - void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *device, ble_drv_adv_evt_callback_t evt_handler) { mp_adv_observer = device; adv_event_handler = evt_handler; } -void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb) { +void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic) { bleio_service_obj_t *service = characteristic->service; bleio_device_obj_t *device = MP_OBJ_TO_PTR(service->device); mp_gattc_char_data_observer = characteristic; - gattc_char_data_handle = cb; const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); if (err_code != 0) { @@ -667,7 +646,7 @@ void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gat translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); } - while (gattc_char_data_handle != NULL) { + while (mp_gattc_char_data_observer != NULL) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif @@ -939,13 +918,18 @@ STATIC void on_characteristic_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *respo mp_gattc_disc_char_observer = NULL; } +STATIC void on_read_rsp(ble_gattc_evt_read_rsp_t *response) { + mp_gattc_char_data_observer->value_data = mp_obj_new_bytearray(response->len, response->data); + + mp_gattc_char_data_observer = NULL; +} + STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: BLE_DRIVER_LOG("GAP CONNECT\n"); - m_adv_in_progress = false; gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); ble_gap_conn_params_t conn_params; @@ -1025,17 +1009,7 @@ STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { break; case BLE_GATTC_EVT_READ_RSP: - BLE_DRIVER_LOG("BLE EVT READ RESPONSE, offset: 0x"HEX2_FMT", length: 0x"HEX2_FMT"\n", - p_ble_evt->evt.gattc_evt.params.read_rsp.offset, - p_ble_evt->evt.gattc_evt.params.read_rsp.len); - - gattc_char_data_handle(mp_gattc_char_data_observer, - p_ble_evt->evt.gattc_evt.params.read_rsp.len, - p_ble_evt->evt.gattc_evt.params.read_rsp.data); - - // mark end of read - gattc_char_data_handle = NULL; - + on_read_rsp(&p_ble_evt->evt.gattc_evt.params.read_rsp); break; case BLE_GATTC_EVT_WRITE_RSP: diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index e0f95eefe..3b065c7a9 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -29,26 +29,17 @@ #if BLUETOOTH_SD -#include -#include - -#include "shared-module/bleio/AdvertisementData.h" -#include "shared-module/bleio/Characteristic.h" -#include "shared-module/bleio/Device.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Scanner.h" +#include "shared-bindings/bleio/Service.h" #include "shared-module/bleio/ScanEntry.h" -#include "shared-module/bleio/Scanner.h" -#include "shared-module/bleio/Service.h" typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gattc_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry); -typedef void (*ble_drv_gattc_char_data_callback_t)(bleio_characteristic_obj_t *self, uint16_t length, uint8_t * p_data); uint32_t ble_drv_stack_enable(void); -void ble_drv_stack_disable(void); - uint8_t ble_drv_stack_enabled(void); void ble_drv_address_get(bleio_address_obj_t *address); @@ -67,11 +58,9 @@ void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_c void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler); -void ble_drv_gattc_event_handler_set(bleio_device_obj_t *device, ble_drv_gattc_evt_callback_t evt_handler); - void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); -void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic, ble_drv_gattc_char_data_callback_t cb); +void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic); void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); -- cgit v1.2.3 From 17f13ecc2cf10975bf5ff0631ce4326b9ffbbcf5 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Sun, 22 Jul 2018 16:06:19 +0200 Subject: nrf: Cleanup of the ble driver Moved the functions to classes that they belong to. --- ports/nrf/common-hal/bleio/Adapter.c | 117 ++- ports/nrf/common-hal/bleio/Characteristic.c | 159 +++- ports/nrf/common-hal/bleio/Device.c | 535 +++++++++++++- ports/nrf/common-hal/bleio/Scanner.c | 72 +- ports/nrf/common-hal/bleio/Service.c | 85 ++- ports/nrf/common-hal/bleio/UUID.c | 48 +- ports/nrf/drivers/bluetooth/ble_drv.c | 1038 ++------------------------- ports/nrf/drivers/bluetooth/ble_drv.h | 68 +- ports/nrf/drivers/bluetooth/ble_uart.h | 4 +- shared-bindings/bleio/Characteristic.c | 2 + shared-bindings/bleio/Characteristic.h | 1 + shared-bindings/bleio/Device.c | 24 +- shared-bindings/bleio/Device.h | 2 +- shared-bindings/bleio/Scanner.h | 1 + shared-bindings/bleio/Service.c | 2 +- shared-module/bleio/Characteristic.h | 2 +- shared-module/bleio/Device.h | 2 +- shared-module/bleio/Service.h | 3 +- 18 files changed, 1024 insertions(+), 1141 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index bee9bd395..dd2fd00dd 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -28,32 +28,133 @@ #include #include +#include "ble.h" #include "ble_drv.h" -#include "nrfx.h" -#include "nrf_error.h" +#include "nrfx_power.h" +#include "nrf_nvic.h" #include "nrf_sdm.h" #include "py/nlr.h" -#include "shared-module/bleio/Address.h" +#include "shared-bindings/bleio/Adapter.h" + +STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError, + "Soft device assert, id: 0x%08lX, pc: 0x%08lX", id, pc)); +} + +STATIC uint32_t ble_stack_enable(void) { + nrf_clock_lf_cfg_t clock_config = { + .source = NRF_CLOCK_LF_SRC_XTAL, +#if (BLE_API_VERSION == 4) + .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM +#else + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM +#endif + }; + +#if (BLUETOOTH_SD == 140) + // The SD takes over the POWER IRQ and will fail if the IRQ is already in use + nrfx_power_uninit(); +#endif + + uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); + if (err_code != NRF_SUCCESS) + return err_code; + + err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); + if (err_code != NRF_SUCCESS) + return err_code; + + uint32_t app_ram_start; +#if (BLE_API_VERSION == 2) + ble_enable_params_t ble_enable_params = { + .gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, + .gap_enable_params.central_conn_count = 1, + .gap_enable_params.periph_conn_count = 1, + }; + + app_ram_start = 0x200039c0; + err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); +#else + app_ram_start = 0x20004000; + + ble_cfg_t ble_conf; + ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM; + ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT; + ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.gap_cfg.role_count_cfg.periph_role_count = 1; + ble_conf.gap_cfg.role_count_cfg.central_role_count = 1; + err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM; + ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + err_code = sd_ble_enable(&app_ram_start); +#endif + + return err_code; +} void common_hal_bleio_adapter_set_enabled(bool enabled) { - uint32_t err_code; + const bool is_enabled = common_hal_bleio_adapter_get_enabled(); + // Don't enable or disable twice + if ((is_enabled && enabled) || (!is_enabled && !enabled)) { + return; + } + + uint32_t err_code; if (enabled) { - err_code = ble_drv_stack_enable(); + err_code = ble_stack_enable(); } else { err_code = sd_softdevice_disable(); } if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to change softdevice status, error: 0x%08lX", err_code)); + "Failed to change softdevice state, error: 0x%08lX", err_code)); } } bool common_hal_bleio_adapter_get_enabled(void) { - return ble_drv_stack_enabled(); + uint8_t is_enabled; + + const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to get softdevice state, error: 0x%08lX", err_code)); + } + + return is_enabled; } void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { - ble_drv_address_get(address); + ble_gap_addr_t local_address; + uint32_t err_code; + + common_hal_bleio_adapter_set_enabled(true); + +#if (BLE_API_VERSION == 2) + err_code = sd_ble_gap_address_get(&local_address); +#else + err_code = sd_ble_gap_addr_get(&local_address); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to get local address, error: 0x%08lX", err_code)); + } + + address->type = local_address.addr_type; + memcpy(address->value, local_address.addr, BLEIO_ADDRESS_BYTES); } diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 35b4f5e24..040cacc3f 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -24,26 +24,173 @@ * THE SOFTWARE. */ +#include +#include + #include "ble_drv.h" +#include "ble_gatts.h" +#include "nrf_soc.h" +#include "py/nlr.h" #include "shared-module/bleio/Characteristic.h" -#include "shared-module/bleio/Device.h" + +static volatile bleio_characteristic_obj_t *m_read_characteristic; +static volatile uint8_t m_tx_in_progress; +static nrf_mutex_t *m_write_mutex; +//static volatile bool m_write_done; + +STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + const uint16_t conn_handle = device->conn_handle; + + ble_gatts_value_t gatts_value = { + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to write gatts value, status: 0x%08lX", err_code)); + } +} + +STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + uint16_t hvx_len = bufinfo->len; + + ble_gatts_hvx_params_t hvx_params = { + .handle = characteristic->handle, + .type = BLE_GATT_HVX_NOTIFICATION, + .p_len = &hvx_len, + .p_data = bufinfo->buf, + }; + + while (m_tx_in_progress > MAX_TX_IN_PROGRESS) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to notify attribute value, status: 0x%08lX", err_code)); + } + + m_tx_in_progress += 1; +} + +STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { + bleio_service_obj_t *service = characteristic->service; + bleio_device_obj_t *device = service->device; + + m_read_characteristic = characteristic; + + const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to read attribute value, status: 0x%08lX", err_code)); + } + + while (m_read_characteristic != NULL) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } +} + +STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + uint16_t conn_handle = device->conn_handle; + uint32_t err_code; + + ble_gattc_write_params_t write_params; + write_params.write_op = BLE_GATT_OP_WRITE_REQ; + + if (characteristic->props.write_wo_resp) { + write_params.write_op = BLE_GATT_OP_WRITE_CMD; + } + + write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; + write_params.handle = characteristic->handle; + write_params.offset = 0; + write_params.len = bufinfo->len; + write_params.p_value = bufinfo->buf; + + if (write_params.write_op == BLE_GATT_OP_WRITE_CMD) { + err_code = sd_mutex_acquire(m_write_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to acquire mutex, status: 0x%08lX", err_code)); + } + } + + err_code = sd_ble_gattc_write(conn_handle, &write_params); + if (err_code != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to write attribute value, status: 0x%08lX", err_code)); + } + + while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_write_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to release mutex, status: 0x%08lX", err_code)); + } +} + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { +#if (BLE_API_VERSION == 4) + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; + break; +#else + case BLE_EVT_TX_COMPLETE: + m_tx_in_progress -= ble_evt->evt.common_evt.params.tx_complete.count; + break; +#endif + + case BLE_GATTC_EVT_READ_RSP: + { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); + m_read_characteristic = NULL; + break; + } + + case BLE_GATTC_EVT_WRITE_RSP: + sd_mutex_release(m_write_mutex); +// m_write_done = true; + break; + } +} + +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) { + ble_drv_add_event_handler(on_ble_evt, NULL); +} void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { - ble_drv_attr_c_read(self); + gattc_read(self); } void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { - const bleio_device_obj_t *device = MP_OBJ_TO_PTR(self->service->device); + const bleio_device_obj_t *device = self->service->device; if (device->is_peripheral) { // TODO: Add indications if (self->props.notify) { - ble_drv_attr_s_notify(self, bufinfo); + gatts_notify(self, bufinfo); } else { - ble_drv_attr_s_write(self, bufinfo); + gatts_write(self, bufinfo); } } else { - ble_drv_attr_c_write(self, bufinfo); + gattc_write(self, bufinfo); } } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 9e7b382dd..195b6cd32 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -24,49 +24,528 @@ * THE SOFTWARE. */ +#include #include +#include "ble.h" #include "ble_drv.h" -#include "ble_gap.h" -#include "ble_gatt.h" -#include "ble_types.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Device.h" #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/UUID.h" -STATIC void gap_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - if (event_id == BLE_GAP_EVT_CONNECTED) { - device->conn_handle = conn_handle; - } else if (event_id == BLE_GAP_EVT_DISCONNECTED) { - device->conn_handle = BLE_CONN_HANDLE_INVALID; +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) +#define BLE_SLAVE_LATENCY 0 +#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) + +#define BLE_ADV_LENGTH_FIELD_SIZE 1 +#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 +#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 + +#ifndef BLE_GAP_ADV_MAX_SIZE +#define BLE_GAP_ADV_MAX_SIZE 31 +#endif + +static bleio_service_obj_t *m_char_discovery_service; +static volatile bool m_discovery_successful; +static nrf_mutex_t *m_discovery_mutex; + +#if (BLUETOOTH_SD == 140) +static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + +static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; + +static ble_data_t m_scan_buffer = { + .p_data = m_scan_buffer_data, + .len = BLE_GAP_SCAN_BUFFER_MIN +}; +#endif + +STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) { + common_hal_bleio_adapter_set_enabled(true); + + uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE]; + uint8_t byte_pos = 0; + uint32_t err_code; + +#define ADD_FIELD(field, len) \ + do { \ + if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \ + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, \ + "Can not fit data into the advertisment packet")); \ + } \ + adv_data[byte_pos] = (field); \ + byte_pos += (len); \ + } while (0) + + GET_STR_DATA_LEN(device->name, name_data, name_len); + if (name_len > 0) { + ble_gap_conn_sec_mode_t sec_mode; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + // TODO: Shorten if too long + + ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + name_len, BLE_ADV_LENGTH_FIELD_SIZE); + ADD_FIELD(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, BLE_ADV_AD_TYPE_FIELD_SIZE); + + memcpy(&adv_data[byte_pos], name_data, name_len); + byte_pos += name_len; + } + + // set flags, default to disc mode + if (raw_data->len == 0) { + ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE, BLE_ADV_LENGTH_FIELD_SIZE); + ADD_FIELD(BLE_GAP_AD_TYPE_FLAGS, BLE_AD_TYPE_FLAGS_DATA_SIZE); + ADD_FIELD(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE, BLE_AD_TYPE_FLAGS_DATA_SIZE); + } else { + if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Can not fit data into the advertisment packet")); + } + + memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len); + byte_pos += raw_data->len; + } + + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + if (service_list->len > 0) { + bool has_128bit_services = false; + bool has_16bit_services = false; + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->is_secondary) { + continue; + } + + if (service->uuid->type == UUID_TYPE_16BIT) { + has_16bit_services = true; + } + + if (service->uuid->type == UUID_TYPE_128BIT) { + has_128bit_services = true; + } + } + + if (has_16bit_services) { + const uint8_t size_byte_pos = byte_pos; + uint8_t uuid_total_size = 0; + + // skip length byte for now, apply total length post calculation + byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + + ADD_FIELD(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE); + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + uint8_t encoded_size = 0; + + if ((service->uuid->type != UUID_TYPE_16BIT) || service->is_secondary) { + continue; + } + + ble_uuid_t uuid; + uuid.type = BLE_UUID_TYPE_BLE; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + uuid_total_size += encoded_size; + byte_pos += encoded_size; + } + + adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); + } + + if (has_128bit_services) { + const uint8_t size_byte_pos = byte_pos; + uint8_t uuid_total_size = 0; + + // skip length byte for now, apply total length post calculation + byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + + ADD_FIELD(BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE); + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + uint8_t encoded_size = 0; + + if ((service->uuid->type != UUID_TYPE_128BIT) || service->is_secondary) { + continue; + } + + ble_uuid_t uuid; + uuid.type = service->uuid->uuid_vs_idx; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + uuid_total_size += encoded_size; + byte_pos += encoded_size; + } + + adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); + } + } + +#if (BLUETOOTH_SD == 132) + err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0); + if (err_code != NRF_SUCCESS) { + return err_code; + } +#endif + + static ble_gap_adv_params_t m_adv_params = { + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), +#if (BLUETOOTH_SD == 140) + .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED, + .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, + .filter_policy = BLE_GAP_ADV_FP_ANY, + .primary_phy = BLE_GAP_PHY_1MBPS, +#else + .type = BLE_GAP_ADV_TYPE_ADV_IND, + .fp = BLE_GAP_ADV_FP_ANY, +#endif + }; + + if (!connectable) { +#if (BLUETOOTH_SD == 140) + m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; +#else + m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; +#endif } + + common_hal_bleio_device_stop_advertising(device); + +#if (BLUETOOTH_SD == 140) + const ble_gap_adv_data_t ble_gap_adv_data = { + .adv_data.p_data = adv_data, + .adv_data.len = byte_pos, + }; + + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM); +#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4) + err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_CUSTOM); +#else + err_code = sd_ble_gap_adv_start(&m_adv_params); +#endif + + return err_code; } -STATIC void gatts_event_handler(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { +STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) { + m_discovery_successful = false; + + uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to discover serivices, status: 0x%08lX", err_code)); + } + + err_code = sd_mutex_acquire(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to acquire mutex, status: 0x%08lX", err_code)); + } + + while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to release mutex, status: 0x%08lX", err_code)); + } + return m_discovery_successful; } -void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data) { - if (adv_data->connectable) { - ble_drv_gap_event_handler_set(device, gap_event_handler); - ble_drv_gatts_event_handler_set(device, gatts_event_handler); +STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) { + m_char_discovery_service = service; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = service->end_handle; + + m_discovery_successful = false; + + uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range); + if (err_code != 0) { + return false; + } + + err_code = sd_mutex_acquire(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to acquire mutex, status: 0x%08lX", err_code)); } - ble_drv_advertise_data(adv_data); + while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to release mutex, status: 0x%08lX", err_code)); + } + + return m_discovery_successful; +} + +STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_device_obj_t *device) { + for (size_t i = 0; i < response->count; ++i) { + const ble_gattc_service_t *gattc_service = &response->services[i]; + + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; + service->device = device; + service->char_list = mp_obj_new_list(0, NULL); + service->start_handle = gattc_service->handle_range.start_handle; + service->end_handle = gattc_service->handle_range.end_handle; + service->handle = gattc_service->handle_range.start_handle; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_service->uuid.uuid & 0xFF; + uuid->value[1] = gattc_service->uuid.uuid >> 8; + service->uuid = uuid; + + mp_obj_list_append(device->service_list, service); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + + const uint32_t err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to release mutex, status: 0x%08lX", err_code)); + } +} + +STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_device_obj_t *device) { + for (size_t i = 0; i < response->count; ++i) { + const ble_gattc_char_t *gattc_char = &response->chars[i]; + + bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); + characteristic->base.type = &bleio_characteristic_type; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_char->uuid.uuid & 0xFF; + uuid->value[1] = gattc_char->uuid.uuid >> 8; + characteristic->uuid = uuid; + + characteristic->props.broadcast = gattc_char->char_props.broadcast; + characteristic->props.indicate = gattc_char->char_props.indicate; + characteristic->props.notify = gattc_char->char_props.notify; + characteristic->props.read = gattc_char->char_props.read; + characteristic->props.write = gattc_char->char_props.write; + characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; + characteristic->handle = gattc_char->handle_value; + + characteristic->service_handle = m_char_discovery_service->handle; + characteristic->service = m_char_discovery_service; + + mp_obj_list_append(m_char_discovery_service->char_list, MP_OBJ_FROM_PTR(characteristic)); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + + const uint32_t err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to release mutex, status: 0x%08lX", err_code)); + } +} + +STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t *device) { + uint32_t err_code; + + if (memcmp(report->peer_addr.addr, device->address.value, BLEIO_ADDRESS_BYTES) != 0) { +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to continue scanning, status: 0x%0xlX", err_code)); + } +#endif + return; + } + + ble_gap_scan_params_t scan_params = { + .active = 1, + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(100, UNIT_0_625_MS), + }; + + ble_gap_addr_t addr; + memset(&addr, 0, sizeof(addr)); + + addr.addr_type = report->peer_addr.addr_type; + memcpy(addr.addr, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); + + ble_gap_conn_params_t conn_params = { + .min_conn_interval = BLE_MIN_CONN_INTERVAL, + .max_conn_interval = BLE_MAX_CONN_INTERVAL, + .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, + .slave_latency = BLE_SLAVE_LATENCY, + }; + +#if (BLE_API_VERSION == 2) + err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params); +#else + err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to connect, status: 0x%08lX", err_code)); + } +} + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { + bleio_device_obj_t *device = (bleio_device_obj_t*)device_in; + + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + { + ble_gap_conn_params_t conn_params; + device->conn_handle = ble_evt->evt.gap_evt.conn_handle; + + sd_ble_gap_ppcp_get(&conn_params); + sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + break; + } + + case BLE_GAP_EVT_DISCONNECTED: + device->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GAP_EVT_ADV_REPORT: + on_adv_report(&ble_evt->evt.gap_evt.params.adv_report, device); + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device); + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device); + break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + sd_ble_gatts_sys_attr_set(ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0); + break; + +#if (BLE_API_VERSION == 4) + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + sd_ble_gatts_exchange_mtu_reply(device->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); + break; +#endif + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sd_ble_gap_sec_params_reply(device->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: + { + ble_gap_evt_conn_param_update_request_t *request = &ble_evt->evt.gap_evt.params.conn_param_update_request; + sd_ble_gap_conn_param_update(device->conn_handle, &request->conn_params); + break; + } + } +} + +void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) { + if (connectable) { + ble_drv_add_event_handler(on_ble_evt, device); + } + + const uint32_t err_code = set_advertisement_data(device, connectable, raw_data); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to start advertisment, status: 0x%08lX", err_code)); + } } void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { - (void)device; + uint32_t err_code; + +#if (BLUETOOTH_SD == 140) + if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + return; - ble_drv_advertise_stop(); + err_code = sd_ble_gap_adv_stop(m_adv_handle); +#else + err_code = sd_ble_gap_adv_stop(); +#endif + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to stop advertisment, status: 0x%08lX", err_code)); + } } void common_hal_bleio_device_connect(bleio_device_obj_t *device) { - ble_drv_gap_event_handler_set(device, gap_event_handler); + ble_drv_add_event_handler(on_ble_evt, device); - ble_drv_connect(device); + ble_gap_scan_params_t scan_params = { + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(100, UNIT_0_625_MS), +#if (BLUETOOTH_SD == 140) + .scan_phys = BLE_GAP_PHY_1MBPS, +#endif + }; + + common_hal_bleio_adapter_set_enabled(true); + + uint32_t err_code; +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer); +#else + err_code = sd_ble_gap_scan_start(&scan_params); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to start scanning, status: 0x%0xlX", err_code)); + } while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { #ifdef MICROPY_VM_HOOK_LOOP @@ -76,13 +555,23 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { // TODO: read name + if (m_discovery_mutex == NULL) { + m_discovery_mutex = m_new_ll(nrf_mutex_t, 1); + + err_code = sd_mutex_new(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to create mutex, status: 0x%0xlX", err_code)); + } + } + // find services - bool found_service = ble_drv_discover_services(device, BLE_GATT_HANDLE_START); + bool found_service = discover_services(device, BLE_GATT_HANDLE_START); while (found_service) { const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); const bleio_service_obj_t *service = service_list->items[service_list->len - 1]; - found_service = ble_drv_discover_services(device, service->end_handle + 1); + found_service = discover_services(device, service->end_handle + 1); } // find characteristics in each service @@ -90,7 +579,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { for (size_t i = 0; i < service_list->len; ++i) { bleio_service_obj_t *service = service_list->items[i]; - bool found_char = ble_drv_discover_characteristic(device, service, service->start_handle); + bool found_char = discover_characteristics(device, service, service->start_handle); while (found_char) { const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1]; @@ -100,11 +589,11 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { break; } - found_char = ble_drv_discover_characteristic(device, service, next_handle); + found_char = discover_characteristics(device, service, next_handle); } } } void common_hal_bleio_device_disconnect(bleio_device_obj_t *device) { - ble_drv_disconnect(device); + sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index 150c417a3..17af49621 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -28,25 +28,83 @@ #include #include "ble_drv.h" +#include "ble_gap.h" #include "py/mphal.h" +#include "py/nlr.h" +#include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/ScanEntry.h" #include "shared-bindings/bleio/Scanner.h" #include "shared-module/bleio/ScanEntry.h" -STATIC void adv_event_handler(bleio_scanner_obj_t *self, bleio_scanentry_obj_t *entry) { +#if (BLUETOOTH_SD == 140) +static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; + +static ble_data_t m_scan_buffer = { + m_scan_buffer_data, + BLE_GAP_SCAN_BUFFER_MIN +}; +#endif + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { + bleio_scanner_obj_t *scanner = (bleio_scanner_obj_t*)scanner_in; + ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report; + + if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) { + return; + } + // TODO: Don't add new entry for each item, group by address and update + bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); + entry->base.type = &bleio_scanentry_type; + entry->rssi = report->rssi; - mp_obj_list_append(self->adv_reports, entry); + entry->address.type = report->peer_addr.addr_type; + memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); - ble_drv_scan_continue(); +#if (BLUETOOTH_SD == 140) + entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data); +#else + entry->data = mp_obj_new_bytearray(report->dlen, report->data); +#endif + + mp_obj_list_append(scanner->adv_reports, entry); + +#if (BLUETOOTH_SD == 140) + const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to continue scanning, status: 0x%0xlX", err_code)); + } +#endif } void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) { - ble_drv_adv_report_handler_set(self, adv_event_handler); + ble_drv_add_event_handler(on_ble_evt, self); + + ble_gap_scan_params_t scan_params = { + .interval = MSEC_TO_UNITS(self->interval, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(self->window, UNIT_0_625_MS), +#if (BLUETOOTH_SD == 140) + .scan_phys = BLE_GAP_PHY_1MBPS, +#endif + }; + + common_hal_bleio_adapter_set_enabled(true); - ble_drv_scan_start(self->interval, self->window); + uint32_t err_code; +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer); +#else + err_code = sd_ble_gap_scan_start(&scan_params); +#endif - mp_hal_delay_ms(timeout); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to start scanning, status: 0x%0xlX", err_code)); + } - ble_drv_scan_stop(); + if (timeout > 0) { + mp_hal_delay_ms(timeout); + sd_ble_gap_scan_stop(); + } } diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index b6e0595b1..9e376b333 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -25,14 +25,91 @@ */ #include "ble_drv.h" -#include "shared-module/bleio/Service.h" +#include "ble.h" +#include "py/nlr.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/Adapter.h" void common_hal_bleio_service_construct(bleio_service_obj_t *self) { - ble_drv_service_add(self); + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = self->uuid->value[0] | (self->uuid->value[1] << 8) + }; + + if (self->uuid->type == UUID_TYPE_128BIT) { + uuid.type = self->uuid->uuid_vs_idx; + } + + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (self->is_secondary) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } + + common_hal_bleio_adapter_set_enabled(true); + + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &self->handle); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to add service, status: 0x%08lX", err_code)); + } } void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { - if (ble_drv_characteristic_add(characteristic)) { - characteristic->service = self; + ble_gatts_char_md_t char_md = { + .char_props.broadcast = characteristic->props.broadcast, + .char_props.read = characteristic->props.read, + .char_props.write_wo_resp = characteristic->props.write_wo_resp, + .char_props.write = characteristic->props.write, + .char_props.notify = characteristic->props.notify, + .char_props.indicate = characteristic->props.indicate, + }; + + ble_gatts_attr_md_t cccd_md = { + .vloc = BLE_GATTS_VLOC_STACK, + }; + + if (char_md.char_props.notify || char_md.char_props.indicate) { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + + char_md.p_cccd_md = &cccd_md; } + + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = characteristic->uuid->value[0] | (characteristic->uuid->value[1] << 8), + }; + + if (characteristic->uuid->type == UUID_TYPE_128BIT) + uuid.type = characteristic->uuid->uuid_vs_idx; + + ble_gatts_attr_md_t attr_md = { + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = 1, + }; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + ble_gatts_attr_t attr_char_value = { + .p_uuid = &uuid, + .p_attr_md = &attr_md, + .init_len = sizeof(uint8_t), + .max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3), + }; + + ble_gatts_char_handles_t handles; + + uint32_t err_code; + err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle, &char_md, &attr_char_value, &handles); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to add characteristic, status: 0x%08lX", err_code)); + } + + characteristic->user_desc_handle = handles.user_desc_handle; + characteristic->cccd_handle = handles.cccd_handle; + characteristic->sccd_handle = handles.sccd_handle; + characteristic->handle = handles.value_handle; + characteristic->service = self; } diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index e655589a6..4d4c8c9fb 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -25,10 +25,13 @@ * THE SOFTWARE. */ +#include "ble.h" #include "ble_drv.h" #include "common-hal/bleio/UUID.h" +#include "nrf_error.h" #include "py/objstr.h" #include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" #include "shared-bindings/bleio/UUID.h" #define UUID_STR_16BIT_LEN 6 @@ -59,37 +62,44 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uui } else if (str_len == UUID_STR_128BIT_LEN) { self->type = UUID_TYPE_128BIT; - uint8_t buffer[16]; - buffer[0] = xdigit_8b_value(str_data[35], str_data[34]); - buffer[1] = xdigit_8b_value(str_data[33], str_data[32]); - buffer[2] = xdigit_8b_value(str_data[31], str_data[30]); - buffer[3] = xdigit_8b_value(str_data[29], str_data[28]); - buffer[4] = xdigit_8b_value(str_data[27], str_data[26]); - buffer[5] = xdigit_8b_value(str_data[25], str_data[24]); + ble_uuid128_t vs_uuid; + vs_uuid.uuid128[0] = xdigit_8b_value(str_data[35], str_data[34]); + vs_uuid.uuid128[1] = xdigit_8b_value(str_data[33], str_data[32]); + vs_uuid.uuid128[2] = xdigit_8b_value(str_data[31], str_data[30]); + vs_uuid.uuid128[3] = xdigit_8b_value(str_data[29], str_data[28]); + vs_uuid.uuid128[4] = xdigit_8b_value(str_data[27], str_data[26]); + vs_uuid.uuid128[5] = xdigit_8b_value(str_data[25], str_data[24]); // 23 '-' - buffer[6] = xdigit_8b_value(str_data[22], str_data[21]); - buffer[7] = xdigit_8b_value(str_data[20], str_data[19]); + vs_uuid.uuid128[6] = xdigit_8b_value(str_data[22], str_data[21]); + vs_uuid.uuid128[7] = xdigit_8b_value(str_data[20], str_data[19]); // 18 '-' - buffer[8] = xdigit_8b_value(str_data[17], str_data[16]); - buffer[9] = xdigit_8b_value(str_data[15], str_data[14]); + vs_uuid.uuid128[8] = xdigit_8b_value(str_data[17], str_data[16]); + vs_uuid.uuid128[9] = xdigit_8b_value(str_data[15], str_data[14]); // 13 '-' - buffer[10] = xdigit_8b_value(str_data[12], str_data[11]); - buffer[11] = xdigit_8b_value(str_data[10], str_data[9]); + vs_uuid.uuid128[10] = xdigit_8b_value(str_data[12], str_data[11]); + vs_uuid.uuid128[11] = xdigit_8b_value(str_data[10], str_data[9]); // 8 '-' self->value[0] = xdigit_8b_value(str_data[7], str_data[6]); self->value[1] = xdigit_8b_value(str_data[5], str_data[4]); - buffer[14] = xdigit_8b_value(str_data[3], str_data[2]); - buffer[15] = xdigit_8b_value(str_data[1], str_data[0]); + vs_uuid.uuid128[14] = xdigit_8b_value(str_data[3], str_data[2]); + vs_uuid.uuid128[15] = xdigit_8b_value(str_data[1], str_data[0]); + + common_hal_bleio_adapter_set_enabled(true); + + const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to add Vendor Specific UUID, status: 0x%08lX", err_code)); + } - ble_drv_uuid_add_vs(buffer, &self->uuid_vs_idx); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Invalid UUID string length")); + "Invalid UUID string length")); } return; @@ -113,10 +123,10 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uui void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { if (self->type == UUID_TYPE_16BIT) { mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->value[1], self->value[0]); + self->value[1], self->value[0]); } else { mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", - self->value[1], self->value[0], self->uuid_vs_idx); + self->value[1], self->value[0], self->uuid_vs_idx); } } diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c index 6d32ff6f9..0b6daf711 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ b/ports/nrf/drivers/bluetooth/ble_drv.c @@ -25,1027 +25,73 @@ * THE SOFTWARE. */ -#if BLUETOOTH_SD - -#include -#include #include +#include -#if (BLUETOOTH_SD == 132) -#define NRF52 // Needed for SD132 v2 -#endif - -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/ScanEntry.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" -#include "shared-module/bleio/Device.h" -#include "py/objstr.h" -#include "py/runtime.h" -#include "supervisor/shared/translate.h" +#include "ble.h" #include "ble_drv.h" #include "nrf_nvic.h" #include "nrf_sdm.h" -#include "nrfx_power.h" -#include "py/objstr.h" -#include "py/runtime.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/ScanEntry.h" -#include "shared-bindings/bleio/UUID.h" - -#define BLE_DRIVER_LOG printf - -#define BLE_ADV_LENGTH_FIELD_SIZE 1 -#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 -#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 - -#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) -#define UNIT_0_625_MS (625) -#define UNIT_10_MS (10000) - -#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) -#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) -#define BLE_SLAVE_LATENCY 0 -#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) - -#ifndef BLE_GAP_ADV_MAX_SIZE -#define BLE_GAP_ADV_MAX_SIZE 31 -#endif - -#define SD_TEST_OR_ENABLE() \ -if (ble_drv_stack_enabled() == 0) { \ - (void)ble_drv_stack_enable(); \ -} - -static ble_drv_adv_evt_callback_t adv_event_handler; -static ble_drv_gatts_evt_callback_t gatts_event_handler; -static ble_drv_gap_evt_callback_t gap_event_handler; - -static bleio_characteristic_obj_t *mp_gattc_char_data_observer; -static bleio_device_obj_t *mp_gattc_disc_service_observer; -static bleio_service_obj_t *mp_gattc_disc_char_observer; -static bleio_address_obj_t *mp_connect_address; -static bleio_device_obj_t *mp_gatts_observer; -static bleio_scanner_obj_t *mp_adv_observer; -static bleio_device_obj_t *mp_gap_observer; - -static volatile bool m_primary_service_found; -static volatile bool m_characteristic_found; -static volatile bool m_tx_in_progress; -static volatile bool m_write_done; +#include "py/misc.h" nrf_nvic_state_t nrf_nvic_state = { 0 }; -#if (BLUETOOTH_SD == 140) -static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; -static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; - -static ble_data_t m_scan_buffer = -{ - m_scan_buffer_data, - BLE_GAP_SCAN_BUFFER_MIN -}; -#endif - -void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { - BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!"); -} - -uint32_t ble_drv_stack_enable(void) { - nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_XTAL, - .rc_ctiv = 0, - .rc_temp_ctiv = 0, -#if (BLE_API_VERSION == 4) - .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM -#else - .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM -#endif - }; - -#if (BLUETOOTH_SD == 140) - // The SD takes over the POWER IRQ and will fail if the IRQ is already in use - nrfx_power_uninit(); -#endif - - uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); - if (err_code != NRF_SUCCESS) - BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code); - - err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); - if (err_code != NRF_SUCCESS) - BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code); - - // Enable BLE stack. - uint32_t app_ram_start; -#if (BLE_API_VERSION == 2) - ble_enable_params_t ble_enable_params; - memset(&ble_enable_params, 0x00, sizeof(ble_enable_params)); - ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT; - ble_enable_params.gatts_enable_params.service_changed = 0; - ble_enable_params.gap_enable_params.periph_conn_count = 1; - ble_enable_params.gap_enable_params.central_conn_count = 1; - - app_ram_start = 0x200039c0; - err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); // 8K SD headroom from linker script. -#else - app_ram_start = 0x20004000; - err_code = sd_ble_enable(&app_ram_start); -#endif - - if (err_code != NRF_SUCCESS) { - BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); - BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code); - } - - return err_code; -} - -uint8_t ble_drv_stack_enabled(void) { - uint8_t is_enabled; - uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); - - if (err_code != NRF_SUCCESS) { - BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code); - } - - return is_enabled; -} - -void ble_drv_address_get(bleio_address_obj_t *address) { - SD_TEST_OR_ENABLE(); - - ble_gap_addr_t local_ble_addr; -#if (BLE_API_VERSION == 2) - uint32_t err_code = sd_ble_gap_address_get(&local_ble_addr); -#else - uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr); -#endif - - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not query for the device address."))); - } - - BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \ - "address: " HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT ":" \ - HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT "\n", \ - local_ble_addr.addr_type, \ - local_ble_addr.addr[5], local_ble_addr.addr[4], local_ble_addr.addr[3], \ - local_ble_addr.addr[2], local_ble_addr.addr[1], local_ble_addr.addr[0]); - - address->type = local_ble_addr.addr_type; - memcpy(address->value, local_ble_addr.addr, BLEIO_ADDRESS_BYTES); -} - -bool ble_drv_uuid_add_vs(uint8_t *uuid, uint8_t *idx) { - SD_TEST_OR_ENABLE(); - - if (sd_ble_uuid_vs_add((ble_uuid128_t const *)uuid, idx) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Vendor Specific 128-bit UUID."))); - } - - return true; -} - -void ble_drv_service_add(bleio_service_obj_t *service) { - SD_TEST_OR_ENABLE(); - - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) - }; - - if (service->uuid->type == UUID_TYPE_128BIT) { - uuid.type = service->uuid->uuid_vs_idx; - } - - uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; - if (service->is_secondary) { - service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; - } - - if (sd_ble_gatts_service_add(service_type, &uuid, &service->handle) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service."))); - } -} - -bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic) { - ble_gatts_char_md_t char_md; - ble_gatts_attr_md_t cccd_md; - ble_gatts_attr_t attr_char_value; - ble_uuid_t uuid; - ble_gatts_attr_md_t attr_md; - - memset(&char_md, 0, sizeof(char_md)); - - char_md.char_props.broadcast = characteristic->props.broadcast; - char_md.char_props.read = characteristic->props.read; - char_md.char_props.write_wo_resp = characteristic->props.write_wo_resp; - char_md.char_props.write = characteristic->props.write; - char_md.char_props.notify = characteristic->props.notify; - char_md.char_props.indicate = characteristic->props.indicate; - - char_md.p_char_user_desc = NULL; - char_md.p_char_pf = NULL; - char_md.p_user_desc_md = NULL; - char_md.p_sccd_md = NULL; - - if (characteristic->props.notify || characteristic->props.notify) { - memset(&cccd_md, 0, sizeof(cccd_md)); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); - cccd_md.vloc = BLE_GATTS_VLOC_STACK; - char_md.p_cccd_md = &cccd_md; - } else { - char_md.p_cccd_md = NULL; - } - - uuid.type = BLE_UUID_TYPE_BLE; - if (characteristic->uuid->type == UUID_TYPE_128BIT) - uuid.type = characteristic->uuid->uuid_vs_idx; - - uuid.uuid = characteristic->uuid->value[0]; - uuid.uuid += characteristic->uuid->value[1] << 8; - - memset(&attr_md, 0, sizeof(attr_md)); - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); - - attr_md.vloc = BLE_GATTS_VLOC_STACK; - attr_md.rd_auth = 0; - attr_md.wr_auth = 0; - attr_md.vlen = 1; - - memset(&attr_char_value, 0, sizeof(attr_char_value)); - - attr_char_value.p_uuid = &uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = sizeof(uint8_t); - attr_char_value.init_offs = 0; -#if (BLE_API_VERSION == 2) - attr_char_value.max_len = (GATT_MTU_SIZE_DEFAULT - 3); -#else - attr_char_value.max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3); -#endif - - ble_gatts_char_handles_t handles; - - uint32_t err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle, - &char_md, - &attr_char_value, - &handles); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Characteristic. status: 0x%08lX"), err_code)); - } - - // apply handles to object instance - characteristic->handle = handles.value_handle; - characteristic->user_desc_handle = handles.user_desc_handle; - characteristic->cccd_handle = handles.cccd_handle; - characteristic->sccd_handle = handles.sccd_handle; - - return true; -} - -// TODO: Replace with just bleio_device_obj_t + data -bool ble_drv_advertise_data(bleio_advertisement_data_t *adv_params) { - SD_TEST_OR_ENABLE(); - - uint8_t byte_pos = 0; - uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE]; - - GET_STR_DATA_LEN(adv_params->device_name, name_data, name_len); - - if (name_len > 0) { - ble_gap_conn_sec_mode_t sec_mode; - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - - if (sd_ble_gap_device_name_set(&sec_mode, - name_data, - name_len) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply device name in the stack."))); - } - - adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + name_len); - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - - // TODO: Shorten if too long - adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - - memcpy(&adv_data[byte_pos], name_data, name_len); - - byte_pos += name_len; - } - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(adv_params->data, &bufinfo, MP_BUFFER_WRITE); - - // set flags, default to disc mode - if (bufinfo.len == 0) { - adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE); - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - - adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS; - byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE; - - adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; - byte_pos += 1; - } - - const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(adv_params->services); - if (service_list->len > 0) { - bool type_16bit_present = false; - bool type_128bit_present = false; - - for (size_t i = 0; i < service_list->len; ++i) { - const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); - - if (service->uuid->type == UUID_TYPE_16BIT) { - type_16bit_present = true; - } - - if (service->uuid->type == UUID_TYPE_128BIT) { - type_128bit_present = true; - } - } - - if (type_16bit_present) { - uint8_t size_byte_pos = byte_pos; - - // skip length byte for now, apply total length post calculation - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; +__attribute__((aligned(4))) +static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; - adv_data[byte_pos] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; +typedef struct event_handler { + struct event_handler *next; + void *param; + ble_drv_evt_handler_t func; +} event_handler_t; - uint8_t uuid_total_size = 0; - uint8_t encoded_size = 0; +static event_handler_t *m_event_handlers; - for (size_t i = 0; i < service_list->len; ++i) { - const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); - - if (service->uuid->type != UUID_TYPE_16BIT) { - continue; - } - - ble_uuid_t uuid; - uuid.type = BLE_UUID_TYPE_BLE; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); - - // calculate total size of uuids - if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not encode UUID, to check length."))); - } - - // do encoding into the adv buffer - if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisement packet."))); - } - - uuid_total_size += encoded_size; // size of entry - byte_pos += encoded_size; // relative to adv data packet - } - - adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); - } - - if (type_128bit_present) { - uint8_t size_byte_pos = byte_pos; - - // skip length byte for now, apply total length post calculation - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - - adv_data[byte_pos] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - - uint8_t uuid_total_size = 0; - uint8_t encoded_size = 0; - - for (size_t i = 0; i < service_list->len; ++i) { - const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); - - if (service->uuid->type != UUID_TYPE_128BIT) { - continue; - } - - ble_uuid_t uuid; - uuid.type = service->uuid->uuid_vs_idx; - uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); - - // calculate total size of uuids - if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not encode UUID, to check length."))); - } - - // do encoding into the adv buffer - if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisement packet."))); - } - - uuid_total_size += encoded_size; // size of entry - byte_pos += encoded_size; // relative to adv data packet - } +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { + event_handler_t *handler = m_new_ll(event_handler_t, 1); + handler->next = NULL; + handler->param = param; + handler->func = func; - adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); - } - } - - if (bufinfo.len > 0) { - if (byte_pos + bufinfo.len > BLE_GAP_ADV_MAX_SIZE) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not fit data into the advertisement packet."))); - } - - memcpy(adv_data, bufinfo.buf, bufinfo.len); - byte_pos += bufinfo.len; - } - - uint32_t err_code; -#if (BLUETOOTH_SD == 132) - if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); - } -#endif - - static ble_gap_adv_params_t m_adv_params; - - // initialize advertising params - memset(&m_adv_params, 0, sizeof(m_adv_params)); - if (adv_params->connectable) { -#if (BLUETOOTH_SD == 140) - m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; -#else - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; -#endif - } else { -#if (BLUETOOTH_SD == 140) - m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; -#else - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; -#endif - } - - m_adv_params.p_peer_addr = NULL; // undirected advertisement - m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); // approx 8 ms -#if (BLUETOOTH_SD == 140) - m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED; - m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY; - m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS; -#else - m_adv_params.fp = BLE_GAP_ADV_FP_ANY; - m_adv_params.timeout = 0; // infinite advertisement -#endif - - ble_drv_advertise_stop(); - -#if (BLUETOOTH_SD == 140) - const ble_gap_adv_data_t ble_gap_adv_data = { - .adv_data = { - .p_data = adv_data, - .len = byte_pos - } - }; - - if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); - } - err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT); -#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4) - err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT); -#else - err_code = sd_ble_gap_adv_start(&m_adv_params); -#endif - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not start advertisement. status: 0x%02x"), (uint16_t)err_code)); - } - - return true; -} - -void ble_drv_advertise_stop(void) { - uint32_t err_code; - -#if (BLUETOOTH_SD == 140) - if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + if (m_event_handlers == NULL) { + m_event_handlers = handler; return; - - err_code = sd_ble_gap_adv_stop(m_adv_handle); -#else - err_code = sd_ble_gap_adv_stop(); -#endif - - if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { - ble_gatts_value_t gatts_value; - memset(&gatts_value, 0, sizeof(gatts_value)); - - gatts_value.len = len; - gatts_value.offset = 0; - gatts_value.p_value = p_data; - - uint32_t err_code = sd_ble_gatts_value_get(conn_handle, - handle, - &gatts_value); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); } -} - -void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); - uint16_t conn_handle = device->conn_handle; - ble_gatts_value_t gatts_value; - - memset(&gatts_value, 0, sizeof(gatts_value)); - - gatts_value.len = bufinfo->len; - gatts_value.offset = 0; - gatts_value.p_value = bufinfo->buf; - - uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); - - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); - uint16_t conn_handle = device->conn_handle; - ble_gatts_hvx_params_t hvx_params; - uint16_t hvx_len = bufinfo->len; - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = characteristic->handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &hvx_len; - hvx_params.p_data = bufinfo->buf; - - while (m_tx_in_progress) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif - } - - m_tx_in_progress = true; - uint32_t err_code; - if ((err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not notify attribute value. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler) { - mp_gap_observer = device; - gap_event_handler = evt_handler; -} - -void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler) { - mp_gatts_observer = device; - gatts_event_handler = evt_handler; -} - -void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *device, ble_drv_adv_evt_callback_t evt_handler) { - mp_adv_observer = device; - adv_event_handler = evt_handler; -} - -void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic) { - bleio_service_obj_t *service = characteristic->service; - bleio_device_obj_t *device = MP_OBJ_TO_PTR(service->device); - - mp_gattc_char_data_observer = characteristic; - - const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); - } - - while (mp_gattc_char_data_observer != NULL) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif - } -} - -void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { - bleio_device_obj_t *device = MP_OBJ_TO_PTR(characteristic->service->device); - uint16_t conn_handle = device->conn_handle; - - ble_gattc_write_params_t write_params; - write_params.write_op = BLE_GATT_OP_WRITE_REQ; - - if (characteristic->props.write_wo_resp) { - write_params.write_op = BLE_GATT_OP_WRITE_CMD; - } - - write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; - write_params.handle = characteristic->handle; - write_params.offset = 0; - write_params.len = bufinfo->len; - write_params.p_value = bufinfo->buf; - - m_write_done = (write_params.write_op == BLE_GATT_OP_WRITE_CMD); - - uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); - } - - while (m_write_done != true) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif - } -} - -void ble_drv_scan_start(uint16_t interval, uint16_t window) { - SD_TEST_OR_ENABLE(); - - ble_gap_scan_params_t scan_params; - memset(&scan_params, 0, sizeof(ble_gap_scan_params_t)); - - scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(interval, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(window, UNIT_0_625_MS); -#if (BLUETOOTH_SD == 140) - scan_params.scan_phys = BLE_GAP_PHY_1MBPS; -#endif - scan_params.timeout = 0; // Infinite - - uint32_t err_code; -#if (BLUETOOTH_SD == 140) - if ((err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer)) != 0) { -#else - if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) { -#endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not start scanning. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_scan_continue(void) { - SD_TEST_OR_ENABLE(); - -#if (BLUETOOTH_SD == 140) - uint32_t err_code; - if ((err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Can not continue scanning. status: 0x" HEX2_FMT, (uint16_t)err_code)); - } -#endif -} - -void ble_drv_scan_stop(void) { - sd_ble_gap_scan_stop(); -} - -STATIC void ble_drv_connect_scan_callback(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry) { - if (memcmp(entry->address.value, mp_connect_address->value, BLEIO_ADDRESS_BYTES) == 0) { - ble_drv_adv_report_handler_set(NULL, NULL); - - ble_gap_scan_params_t scan_params; - memset(&scan_params, 0, sizeof(scan_params)); - - scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.timeout = 0; - - ble_gap_addr_t addr; - memset(&addr, 0, sizeof(addr)); - - addr.addr_type = entry->address.type; - memcpy(addr.addr, entry->address.value, BLEIO_ADDRESS_BYTES); - - BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n", - addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], addr.addr_type); - - ble_gap_conn_params_t conn_params = { - .min_conn_interval = BLE_MIN_CONN_INTERVAL, - .max_conn_interval = BLE_MAX_CONN_INTERVAL, - .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, - .slave_latency = BLE_SLAVE_LATENCY, - }; - - uint32_t err_code; - #if (BLE_API_VERSION == 2) - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) { - #else - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) { - #endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Can not connect. status: 0x" HEX2_FMT, (uint16_t)err_code)); + event_handler_t *it = m_event_handlers; + while (it->next != NULL) { + if ((it->func == func) && (it->param == param)) { + m_free(handler); + return; } - } -} - -void ble_drv_connect(bleio_device_obj_t *device) { - SD_TEST_OR_ENABLE(); - - mp_connect_address = &device->address; - ble_drv_adv_report_handler_set(NULL, ble_drv_connect_scan_callback); - - ble_drv_scan_start(100, 100); -} - -void ble_drv_disconnect(bleio_device_obj_t *device) { - sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); -} - -bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle) { - mp_gattc_disc_service_observer = device; - - m_primary_service_found = false; - - uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); - if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to discover serivices. status: 0x" HEX2_FMT, (uint16_t)err_code)); - } - while (mp_gattc_disc_service_observer != NULL) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif + it = it->next; } - return m_primary_service_found; + it->next = handler; } -bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) { - BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", device->conn_handle); - - mp_gattc_disc_char_observer = service; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = service->end_handle; - - m_characteristic_found = false; - - uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range); - if (err_code != 0) { - return false; - } - - while (mp_gattc_disc_char_observer != NULL) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP -#endif - } - - return m_characteristic_found; -} - -void ble_drv_discover_descriptors(void) { - -} - -STATIC void on_adv_report(ble_gap_evt_adv_report_t *report) { - bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); - entry->base.type = &bleio_scanentry_type; - - entry->rssi = report->rssi; - - entry->address.type = report->peer_addr.addr_type; - memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); - -#if (BLUETOOTH_SD == 140) - entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data); -#else - entry->data = mp_obj_new_bytearray(report->dlen, report->data); -#endif - - if (adv_event_handler != NULL) { - adv_event_handler(mp_adv_observer, entry); - } -} - -STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response) { - BLE_DRIVER_LOG(">>> service count: %d\n", response->count); - - for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_service_t *gattc_service = &response->services[i]; - - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - service->base.type = &bleio_service_type; - service->char_list = mp_obj_new_list(0, NULL); - service->start_handle = gattc_service->handle_range.start_handle; - service->end_handle = gattc_service->handle_range.end_handle; - service->handle = gattc_service->handle_range.start_handle; - service->device = mp_gattc_disc_service_observer; - - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_service->uuid.uuid & 0xFF; - uuid->value[1] = gattc_service->uuid.uuid >> 8; - service->uuid = uuid; - - mp_obj_list_append(mp_gattc_disc_service_observer->service_list, service); - } - - if (response->count > 0) { - m_primary_service_found = true; - } - - // mark end of service discovery - mp_gattc_disc_service_observer = NULL; -} - -STATIC void on_characteristic_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response) { - BLE_DRIVER_LOG(">>> characteristic count: %d\n", response->count); - - for (size_t i = 0; i < response->count; ++i) { - const ble_gattc_char_t *gattc_char = &response->chars[i]; - - bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); - characteristic->base.type = &bleio_characteristic_type; - - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; - uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; - uuid->value[0] = gattc_char->uuid.uuid & 0xFF; - uuid->value[1] = gattc_char->uuid.uuid >> 8; - characteristic->uuid = uuid; - - characteristic->props.broadcast = gattc_char->char_props.broadcast; - characteristic->props.indicate = gattc_char->char_props.indicate; - characteristic->props.notify = gattc_char->char_props.notify; - characteristic->props.read = gattc_char->char_props.read; - characteristic->props.write = gattc_char->char_props.write; - characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; - characteristic->handle = gattc_char->handle_value; - - characteristic->service_handle = mp_gattc_disc_char_observer->handle; - characteristic->service = mp_gattc_disc_char_observer; - - mp_obj_list_append(mp_gattc_disc_char_observer->char_list, MP_OBJ_FROM_PTR(characteristic)); - } - - if (response->count > 0) { - m_characteristic_found = true; +void SD_EVT_IRQHandler(void) { + uint32_t evt_id; + while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { +// sd_evt_handler(evt_id); } - // mark end of characteristic discovery - mp_gattc_disc_char_observer = NULL; -} - -STATIC void on_read_rsp(ble_gattc_evt_read_rsp_t *response) { - mp_gattc_char_data_observer->value_data = mp_obj_new_bytearray(response->len, response->data); - - mp_gattc_char_data_observer = NULL; -} - -STATIC void ble_evt_handler(ble_evt_t *p_ble_evt) { - printf("%s - 0x%02X\r\n", __func__, p_ble_evt->header.evt_id); - - switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - BLE_DRIVER_LOG("GAP CONNECT\n"); - gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - - ble_gap_conn_params_t conn_params; - (void)sd_ble_gap_ppcp_get(&conn_params); - (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, &conn_params); - break; - - case BLE_GAP_EVT_DISCONNECTED: - BLE_DRIVER_LOG("GAP DISCONNECT\n"); - gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - break; - - case BLE_GATTS_EVT_HVC: - gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gatts_evt.params.hvc.handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - break; - - case BLE_GATTS_EVT_WRITE: - BLE_DRIVER_LOG("GATTS write\n"); - - uint16_t handle = p_ble_evt->evt.gatts_evt.params.write.handle; - uint16_t data_len = p_ble_evt->evt.gatts_evt.params.write.len; - uint8_t * p_data = &p_ble_evt->evt.gatts_evt.params.write.data[0]; - - gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, handle, data_len, p_data); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - BLE_DRIVER_LOG("GAP CONN PARAM UPDATE\n"); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - // No system attributes have been stored. - (void)sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0); - break; - -#if (BLE_API_VERSION == 4) - case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: - BLE_DRIVER_LOG("GATTS EVT EXCHANGE MTU REQUEST\n"); - (void)sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, 23); // MAX MTU size - break; -#endif - -#if (BLE_API_VERSION == 4) - case BLE_GATTS_EVT_HVN_TX_COMPLETE: -#else - case BLE_EVT_TX_COMPLETE: -#endif - BLE_DRIVER_LOG("BLE EVT TX COMPLETE\n"); - m_tx_in_progress = false; - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - BLE_DRIVER_LOG("BLE EVT SEC PARAMS REQUEST\n"); - // pairing not supported - (void)sd_ble_gap_sec_params_reply(p_ble_evt->evt.gatts_evt.conn_handle, - BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, - NULL, NULL); - break; - - case BLE_GAP_EVT_ADV_REPORT: - on_adv_report(&p_ble_evt->evt.gap_evt.params.adv_report); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - BLE_DRIVER_LOG("BLE EVT CONN PARAM UPDATE REQUEST\n"); - - (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, - &p_ble_evt->evt.gap_evt.params.conn_param_update_request.conn_params); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - on_primary_srv_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - on_characteristic_discovery_rsp(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp); - break; - - case BLE_GATTC_EVT_READ_RSP: - on_read_rsp(&p_ble_evt->evt.gattc_evt.params.read_rsp); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - BLE_DRIVER_LOG("BLE EVT WRITE RESPONSE\n"); - m_write_done = true; - break; + while (1) { + uint16_t evt_len = sizeof(m_ble_evt_buf); + const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); + if (err_code != NRF_SUCCESS) { + if (err_code == NRF_ERROR_DATA_SIZE) { + printf("NRF_ERROR_DATA_SIZE\n"); + } - case BLE_GATTC_EVT_HVX: - BLE_DRIVER_LOG("BLE EVT HVX RESPONSE\n"); break; + } - default: - BLE_DRIVER_LOG(">>> unhandled evt: 0x" HEX2_FMT "\n", p_ble_evt->header.evt_id); - break; + event_handler_t *it = m_event_handlers; + while (it != NULL) { + it->func((ble_evt_t *)m_ble_evt_buf, it->param); + it = it->next; + } } } - -#if (BLE_API_VERSION == 2) -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attribute__ ((aligned (4))); -#else -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)] __attribute__ ((aligned (4))); -#endif - -void SD_EVT_IRQHandler(void) { - uint32_t evt_id; - uint32_t err_code; - do { - err_code = sd_evt_get(&evt_id); - // TODO: handle non ble events - } while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS); - - uint16_t evt_len = sizeof(m_ble_evt_buf); - do { - err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); - ble_evt_handler((ble_evt_t *)m_ble_evt_buf); - } while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS); -} - -#endif // BLUETOOTH_SD diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h index 3b065c7a9..426354a19 100644 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ b/ports/nrf/drivers/bluetooth/ble_drv.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,65 +28,26 @@ #ifndef BLUETOOTH_LE_DRIVER_H__ #define BLUETOOTH_LE_DRIVER_H__ -#if BLUETOOTH_SD +#include "ble.h" -#include "shared-bindings/bleio/Device.h" -#include "shared-bindings/bleio/Scanner.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-module/bleio/ScanEntry.h" +#if (BLUETOOTH_SD == 132) && (BLE_API_VERSION == 2) +#define NRF52 +#endif -typedef void (*ble_drv_gap_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gatts_evt_callback_t)(bleio_device_obj_t *device, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_adv_evt_callback_t)(bleio_scanner_obj_t *scanner, bleio_scanentry_obj_t *entry); +#define MAX_TX_IN_PROGRESS 10 -uint32_t ble_drv_stack_enable(void); +#ifndef BLE_GATT_ATT_MTU_DEFAULT + #define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT +#endif -uint8_t ble_drv_stack_enabled(void); +#define BLE_CONN_CFG_TAG_CUSTOM 1 -void ble_drv_address_get(bleio_address_obj_t *address); +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +#define UNIT_0_625_MS (625) +#define UNIT_10_MS (10000) -bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx); +typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); -void ble_drv_service_add(bleio_service_obj_t *service); - -bool ble_drv_characteristic_add(bleio_characteristic_obj_t *characteristic); - -bool ble_drv_advertise_data(bleio_advertisement_data_t *p_adv_params); - -void ble_drv_advertise_stop(void); - -void ble_drv_gap_event_handler_set(bleio_device_obj_t *device, ble_drv_gap_evt_callback_t evt_handler); - -void ble_drv_gatts_event_handler_set(bleio_device_obj_t *device, ble_drv_gatts_evt_callback_t evt_handler); - -void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); - -void ble_drv_attr_c_read(bleio_characteristic_obj_t *characteristic); - -void ble_drv_attr_s_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); - -void ble_drv_attr_s_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); - -void ble_drv_attr_c_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo); - -void ble_drv_scan_start(uint16_t interval, uint16_t window); - -void ble_drv_scan_continue(void); - -void ble_drv_scan_stop(void); - -void ble_drv_adv_report_handler_set(bleio_scanner_obj_t *self, ble_drv_adv_evt_callback_t evt_handler); - -void ble_drv_connect(bleio_device_obj_t *device); - -void ble_drv_disconnect(bleio_device_obj_t *device); - -bool ble_drv_discover_services(bleio_device_obj_t *device, uint16_t start_handle); - -bool ble_drv_discover_characteristic(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle); - -void ble_drv_discover_descriptors(void); - -#endif // BLUETOOTH_SD +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); #endif // BLUETOOTH_LE_DRIVER_H__ diff --git a/ports/nrf/drivers/bluetooth/ble_uart.h b/ports/nrf/drivers/bluetooth/ble_uart.h index 336624cd3..b57a75229 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.h +++ b/ports/nrf/drivers/bluetooth/ble_uart.h @@ -27,7 +27,7 @@ #ifndef BLUETOOTH_LE_UART_H__ #define BLUETOOTH_LE_UART_H__ -#if BLUETOOTH_SD +#include #include "ble_drv.h" @@ -36,6 +36,4 @@ void ble_uart_advertise(void); bool ble_uart_connected(void); bool ble_uart_enabled(void); -#endif // BLUETOOTH_SD - #endif // BLUETOOTH_LE_UART_H__ diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 905babecb..3563d3895 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -125,6 +125,8 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t "Invalid UUID parameter")); } + common_hal_bleio_characteristic_construct(self); + return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h index dd67170d9..0e99e97cc 100644 --- a/shared-bindings/bleio/Characteristic.h +++ b/shared-bindings/bleio/Characteristic.h @@ -31,6 +31,7 @@ extern const mp_obj_type_t bleio_characteristic_type; +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self); extern void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 386261683..8c7cef95f 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -199,7 +199,7 @@ STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) "Can't add services in Central mode")); } - service->device = self_in; + service->device = self; mp_obj_list_append(self->service_list, service); @@ -266,31 +266,21 @@ STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t "Can't advertise in Central mode")); } - enum { ARG_connectable }; + enum { ARG_connectable, ARG_data }; static const mp_arg_t allowed_args[] = { { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // TODO: data - bleio_advertisement_data_t adv_data = { - .device_name = self->name, - .services = mp_obj_new_list(0, NULL), - .data = mp_obj_new_bytearray(0, NULL), - .connectable = args[ARG_connectable].u_bool - }; - - mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); - for (size_t i = 0; i < service_list->len; ++i) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); - if (!service->is_secondary) { - mp_obj_list_append(adv_data.services, service_list->items[i]); - } + mp_buffer_info_t bufinfo = { 0 }; + if (args[ARG_data].u_obj != mp_const_none) { + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); } - common_hal_bleio_device_start_advertising(self, &adv_data); + common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); return mp_const_none; } diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Device.h index d099e5c43..f989736dd 100644 --- a/shared-bindings/bleio/Device.h +++ b/shared-bindings/bleio/Device.h @@ -32,7 +32,7 @@ extern const mp_obj_type_t bleio_device_type; -extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bleio_advertisement_data_t *adv_data); +extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device); extern void common_hal_bleio_device_connect(bleio_device_obj_t *device); extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device); diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h index 03db5cd8b..9bd071747 100644 --- a/shared-bindings/bleio/Scanner.h +++ b/shared-bindings/bleio/Scanner.h @@ -34,5 +34,6 @@ extern const mp_obj_type_t bleio_scanner_type; extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout); +extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 338269a5f..a2f9b9899 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -74,7 +74,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 1, 1, true); bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); self->base.type = &bleio_service_type; - self->device = mp_const_none; + self->device = NULL; self->char_list = mp_obj_new_list(0, NULL); mp_map_t kw_args; diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index 2347c9c30..13f75b2c9 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -33,7 +33,7 @@ typedef struct { mp_obj_base_t base; bleio_service_obj_t *service; - uint16_t service_handle; + uint16_t service_handle; // TODO: Is this needed? bleio_uuid_obj_t *uuid; mp_obj_t value_data; uint16_t handle; diff --git a/shared-module/bleio/Device.h b/shared-module/bleio/Device.h index afbd8f063..8d9ece5ef 100644 --- a/shared-module/bleio/Device.h +++ b/shared-module/bleio/Device.h @@ -36,7 +36,7 @@ typedef struct { bool is_peripheral; mp_obj_t name; bleio_address_obj_t address; - uint16_t conn_handle; + volatile uint16_t conn_handle; mp_obj_t service_list; mp_obj_t notif_handler; mp_obj_t conn_handler; diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h index 1e3f09119..ff506d3f3 100644 --- a/shared-module/bleio/Service.h +++ b/shared-module/bleio/Service.h @@ -28,13 +28,14 @@ #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H #include "common-hal/bleio/UUID.h" +#include "shared-module/bleio/Device.h" typedef struct { mp_obj_base_t base; uint16_t handle; bool is_secondary; bleio_uuid_obj_t *uuid; - mp_obj_t device; + bleio_device_obj_t *device; mp_obj_t char_list; uint16_t start_handle; uint16_t end_handle; -- cgit v1.2.3 From d5a71a4b8a7ffe91ba688c733f10858cc428e9a6 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Sun, 22 Jul 2018 16:23:04 +0200 Subject: nrf: Move bluetooth driver to the 'bluetooth' folder --- ports/nrf/.gitignore | 2 +- ports/nrf/Makefile | 6 +- ports/nrf/bluetooth/ble_drv.c | 97 ++++++++ ports/nrf/bluetooth/ble_drv.h | 53 ++++ ports/nrf/bluetooth/ble_uart.c | 275 +++++++++++++++++++++ ports/nrf/bluetooth/ble_uart.h | 39 +++ ports/nrf/bluetooth/bluetooth_common.mk | 43 ++++ ports/nrf/bluetooth/download_ble_stack.sh | 72 ++++++ ports/nrf/bluetooth/ringbuffer.h | 99 ++++++++ ports/nrf/boards/feather_nrf52832/README.md | 2 +- .../nrf/boards/feather_nrf52840_express/README.md | 4 +- ports/nrf/drivers/bluetooth/ble_drv.c | 97 -------- ports/nrf/drivers/bluetooth/ble_drv.h | 53 ---- ports/nrf/drivers/bluetooth/ble_uart.c | 275 --------------------- ports/nrf/drivers/bluetooth/ble_uart.h | 39 --- ports/nrf/drivers/bluetooth/bluetooth_common.mk | 43 ---- ports/nrf/drivers/bluetooth/download_ble_stack.sh | 72 ------ ports/nrf/drivers/bluetooth/ringbuffer.h | 99 -------- 18 files changed, 684 insertions(+), 686 deletions(-) create mode 100644 ports/nrf/bluetooth/ble_drv.c create mode 100644 ports/nrf/bluetooth/ble_drv.h create mode 100644 ports/nrf/bluetooth/ble_uart.c create mode 100644 ports/nrf/bluetooth/ble_uart.h create mode 100644 ports/nrf/bluetooth/bluetooth_common.mk create mode 100755 ports/nrf/bluetooth/download_ble_stack.sh create mode 100644 ports/nrf/bluetooth/ringbuffer.h delete mode 100644 ports/nrf/drivers/bluetooth/ble_drv.c delete mode 100644 ports/nrf/drivers/bluetooth/ble_drv.h delete mode 100644 ports/nrf/drivers/bluetooth/ble_uart.c delete mode 100644 ports/nrf/drivers/bluetooth/ble_uart.h delete mode 100644 ports/nrf/drivers/bluetooth/bluetooth_common.mk delete mode 100755 ports/nrf/drivers/bluetooth/download_ble_stack.sh delete mode 100644 ports/nrf/drivers/bluetooth/ringbuffer.h diff --git a/ports/nrf/.gitignore b/ports/nrf/.gitignore index ace93515a..227a82e50 100644 --- a/ports/nrf/.gitignore +++ b/ports/nrf/.gitignore @@ -1,6 +1,6 @@ # Nordic files ##################### -drivers/bluetooth/s1*/ +bluetooth/s1*/ # Build files ##################### diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index b059569ab..9f8993977 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -21,7 +21,7 @@ include ../../py/mkenv.mk -include mpconfigport.mk ifneq ($(SD), ) - include drivers/bluetooth/bluetooth_common.mk + include bluetooth/bluetooth_common.mk endif FROZEN_MPY_DIR = freeze @@ -41,6 +41,7 @@ INC += -I$(BUILD) INC += -I$(BUILD)/genhdr INC += -I./../../lib/cmsis/inc INC += -I./boards/$(BOARD) +INC += -I./bluetooth INC += -I./modules/ubluepy INC += -I./modules/ble INC += -I./nrfx @@ -48,9 +49,6 @@ INC += -I./nrfx/hal INC += -I./nrfx/mdk INC += -I./nrfx/drivers/include INC += -I../../lib/mp-readline -INC += -I./drivers/bluetooth -INC += -I./drivers -INC += -I./peripherals INC += -I../../lib/tinyusb/src INC += -I./usb diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c new file mode 100644 index 000000000..0b6daf711 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.c @@ -0,0 +1,97 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "py/misc.h" + +nrf_nvic_state_t nrf_nvic_state = { 0 }; + +__attribute__((aligned(4))) +static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; + +typedef struct event_handler { + struct event_handler *next; + void *param; + ble_drv_evt_handler_t func; +} event_handler_t; + +static event_handler_t *m_event_handlers; + +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { + event_handler_t *handler = m_new_ll(event_handler_t, 1); + handler->next = NULL; + handler->param = param; + handler->func = func; + + if (m_event_handlers == NULL) { + m_event_handlers = handler; + return; + } + + event_handler_t *it = m_event_handlers; + while (it->next != NULL) { + if ((it->func == func) && (it->param == param)) { + m_free(handler); + return; + } + + it = it->next; + } + + it->next = handler; +} + +void SD_EVT_IRQHandler(void) { + uint32_t evt_id; + while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { +// sd_evt_handler(evt_id); + } + + while (1) { + uint16_t evt_len = sizeof(m_ble_evt_buf); + const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); + if (err_code != NRF_SUCCESS) { + if (err_code == NRF_ERROR_DATA_SIZE) { + printf("NRF_ERROR_DATA_SIZE\n"); + } + + break; + } + + event_handler_t *it = m_event_handlers; + while (it != NULL) { + it->func((ble_evt_t *)m_ble_evt_buf, it->param); + it = it->next; + } + } +} diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h new file mode 100644 index 000000000..426354a19 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef BLUETOOTH_LE_DRIVER_H__ +#define BLUETOOTH_LE_DRIVER_H__ + +#include "ble.h" + +#if (BLUETOOTH_SD == 132) && (BLE_API_VERSION == 2) +#define NRF52 +#endif + +#define MAX_TX_IN_PROGRESS 10 + +#ifndef BLE_GATT_ATT_MTU_DEFAULT + #define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT +#endif + +#define BLE_CONN_CFG_TAG_CUSTOM 1 + +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +#define UNIT_0_625_MS (625) +#define UNIT_10_MS (10000) + +typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); + +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); + +#endif // BLUETOOTH_LE_DRIVER_H__ diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c new file mode 100644 index 000000000..b1d54eefa --- /dev/null +++ b/ports/nrf/bluetooth/ble_uart.c @@ -0,0 +1,275 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#if BLUETOOTH_SD + +#include +#include "ble_uart.h" +#include "ringbuffer.h" +#include "py/mphal.h" +#include "lib/utils/interrupt_char.h" + +#if MICROPY_PY_BLE_NUS + +static bleio_uuid_obj_t uuid_obj_service = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, + .value = {0x01, 0x00} +}; + +static bleio_uuid_obj_t uuid_obj_char_tx = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, + .value = {0x03, 0x00} +}; + +static bleio_uuid_obj_t uuid_obj_char_rx = { + .base.type = &bleio_uuid_type, + .type = UUID_128_BIT, + .value = {0x02, 0x00} +}; + +static ubluepy_service_obj_t ble_uart_service = { + .base.type = &ubluepy_service_type, + .p_uuid = &uuid_obj_service, + .type = UBLUEPY_SERVICE_PRIMARY +}; + +static ubluepy_characteristic_obj_t ble_uart_char_rx = { + .base.type = &ubluepy_characteristic_type, + .p_uuid = &uuid_obj_char_rx, + .props = UBLUEPY_PROP_WRITE | UBLUEPY_PROP_WRITE_WO_RESP, + .attrs = 0, +}; + +static ubluepy_characteristic_obj_t ble_uart_char_tx = { + .base.type = &ubluepy_characteristic_type, + .p_uuid = &uuid_obj_char_tx, + .props = UBLUEPY_PROP_NOTIFY, + .attrs = UBLUEPY_ATTR_CCCD, +}; + +static ubluepy_peripheral_obj_t ble_uart_peripheral = { + .base.type = &ubluepy_peripheral_type, + .conn_handle = 0xFFFF, +}; + +static volatile bool m_cccd_enabled; +static volatile bool m_connected; + +ringBuffer_typedef(uint8_t, ringbuffer_t); + +static ringbuffer_t m_rx_ring_buffer; +static ringbuffer_t * mp_rx_ring_buffer = &m_rx_ring_buffer; +static uint8_t m_rx_ring_buffer_data[128]; + +static ubluepy_advertise_data_t m_adv_data_uart_service; + +#if BLUETOOTH_WEBBLUETOOTH_REPL +static ubluepy_advertise_data_t m_adv_data_eddystone_url; +#endif // BLUETOOTH_WEBBLUETOOTH_REPL + +int mp_hal_stdin_rx_chr(void) { + while (isBufferEmpty(mp_rx_ring_buffer)) { + ; + } + + uint8_t byte; + bufferRead(mp_rx_ring_buffer, byte); + return (int)byte; +} + +bool mp_hal_stdin_any(void) { + return !isBufferEmpty(mp_rx_ring_buffer); +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + uint8_t *buf = (uint8_t *)str; + size_t send_len; + + while (len > 0) { + if (len >= 20) { + send_len = 20; // (GATT_MTU_SIZE_DEFAULT - 3) + } else { + send_len = len; + } + + ubluepy_characteristic_obj_t * p_char = &ble_uart_char_tx; + + ble_drv_attr_s_notify(p_char->p_service->p_periph->conn_handle, + p_char->handle, + send_len, + buf); + + len -= send_len; + buf += send_len; + } +} + +void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) { + mp_hal_stdout_tx_strn(str, len); +} + +STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { + ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); + + if (event_id == 16) { // connect event + self->conn_handle = conn_handle; + m_connected = true; + } else if (event_id == 17) { // disconnect event + self->conn_handle = 0xFFFF; // invalid connection handle + m_connected = false; + ble_uart_advertise(); + } +} + +STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { + ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); + (void)self; + + if (event_id == 80) { // gatts write + if (ble_uart_char_tx.cccd_handle == attr_handle) { + m_cccd_enabled = true; + } else if (ble_uart_char_rx.handle == attr_handle) { + for (uint16_t i = 0; i < length; i++) { + #if MICROPY_KBD_EXCEPTION + if (data[i] == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else + #endif + { + bufferWrite(mp_rx_ring_buffer, data[i]); + } + } + } + } +} + +void ble_uart_init0(void) { + uint8_t base_uuid[] = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}; + uint8_t uuid_vs_idx; + + (void)ble_drv_uuid_add_vs(base_uuid, &uuid_vs_idx); + + uuid_obj_service.uuid_vs_idx = uuid_vs_idx; + uuid_obj_char_tx.uuid_vs_idx = uuid_vs_idx; + uuid_obj_char_rx.uuid_vs_idx = uuid_vs_idx; + + (void)ble_drv_service_add(&ble_uart_service); + ble_uart_service.char_list = mp_obj_new_list(0, NULL); + + // add TX characteristic + ble_uart_char_tx.service_handle = ble_uart_service.handle; + bool retval = ble_drv_characteristic_add(&ble_uart_char_tx); + if (retval) { + ble_uart_char_tx.p_service = &ble_uart_service; + } + mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx)); + + // add RX characteristic + ble_uart_char_rx.service_handle = ble_uart_service.handle; + retval = ble_drv_characteristic_add(&ble_uart_char_rx); + if (retval) { + ble_uart_char_rx.p_service = &ble_uart_service; + } + mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx)); + + // setup the peripheral + ble_uart_peripheral.service_list = mp_obj_new_list(0, NULL); + mp_obj_list_append(ble_uart_peripheral.service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); + ble_uart_service.p_periph = &ble_uart_peripheral; + + ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gap_event_handler); + ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gatts_event_handler); + + ble_uart_peripheral.conn_handle = 0xFFFF; + + char device_name[] = "mpus"; + + mp_obj_t service_list = mp_obj_new_list(0, NULL); + mp_obj_list_append(service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); + + mp_obj_t * services = NULL; + mp_uint_t num_services; + mp_obj_get_array(service_list, &num_services, &services); + + m_adv_data_uart_service.p_services = services; + m_adv_data_uart_service.num_of_services = num_services; + m_adv_data_uart_service.p_device_name = (uint8_t *)device_name; + m_adv_data_uart_service.device_name_len = strlen(device_name); + m_adv_data_uart_service.connectable = true; + m_adv_data_uart_service.p_data = NULL; + +#if BLUETOOTH_WEBBLUETOOTH_REPL + // for now point eddystone URL to https://goo.gl/x46FES => https://glennrub.github.io/webbluetooth/micropython/repl/ + static uint8_t eddystone_url_data[27] = {0x2, 0x1, 0x6, + 0x3, 0x3, 0xaa, 0xfe, + 19, 0x16, 0xaa, 0xfe, 0x10, 0xee, 0x3, 'g', 'o', 'o', '.', 'g', 'l', '/', 'x', '4', '6', 'F', 'E', 'S'}; + // eddystone url adv data + m_adv_data_eddystone_url.p_data = eddystone_url_data; + m_adv_data_eddystone_url.data_len = sizeof(eddystone_url_data); + m_adv_data_eddystone_url.connectable = false; +#endif + + m_cccd_enabled = false; + + // initialize ring buffer + m_rx_ring_buffer.size = sizeof(m_rx_ring_buffer_data) + 1; + m_rx_ring_buffer.start = 0; + m_rx_ring_buffer.end = 0; + m_rx_ring_buffer.elems = m_rx_ring_buffer_data; + + m_connected = false; + + ble_uart_advertise(); +} + +void ble_uart_advertise(void) { +#if BLUETOOTH_WEBBLUETOOTH_REPL + while (!m_connected) { + (void)ble_drv_advertise_data(&m_adv_data_uart_service); + mp_hal_delay_ms(500); + (void)ble_drv_advertise_data(&m_adv_data_eddystone_url); + mp_hal_delay_ms(500); + } + + ble_drv_advertise_stop(); +#else + (void)ble_drv_advertise_data(&m_adv_data_uart_service); +#endif // BLUETOOTH_WEBBLUETOOTH_REPL +} + +bool ble_uart_connected(void) { + return (m_connected); +} + +bool ble_uart_enabled(void) { + return (m_cccd_enabled); +} + +#endif // MICROPY_PY_BLE_NUS + +#endif // BLUETOOTH_SD diff --git a/ports/nrf/bluetooth/ble_uart.h b/ports/nrf/bluetooth/ble_uart.h new file mode 100644 index 000000000..b57a75229 --- /dev/null +++ b/ports/nrf/bluetooth/ble_uart.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef BLUETOOTH_LE_UART_H__ +#define BLUETOOTH_LE_UART_H__ + +#include + +#include "ble_drv.h" + +void ble_uart_init0(void); +void ble_uart_advertise(void); +bool ble_uart_connected(void); +bool ble_uart_enabled(void); + +#endif // BLUETOOTH_LE_UART_H__ diff --git a/ports/nrf/bluetooth/bluetooth_common.mk b/ports/nrf/bluetooth/bluetooth_common.mk new file mode 100644 index 000000000..7dad38e9e --- /dev/null +++ b/ports/nrf/bluetooth/bluetooth_common.mk @@ -0,0 +1,43 @@ +ifeq ($(SD), s132) + CFLAGS += -DBLUETOOTH_SD=132 + +ifeq ($(SOFTDEV_VERSION), 2.0.1) + CFLAGS += -DBLE_API_VERSION=2 +else ifeq ($(SOFTDEV_VERSION), 5.0.0) + CFLAGS += -DBLE_API_VERSION=4 +endif +else ifeq ($(SD), s140) + CFLAGS += -DBLUETOOTH_SD=140 + CFLAGS += -DBLE_API_VERSION=4 +else +$(error Incorrect softdevice set flag) +endif + +CFLAGS += -DBLUETOOTH_SD_DEBUG=1 + +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) + +SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex +SOFTDEV_HEX_PATH = bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) +SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME) + +define STACK_MISSING_ERROR + + +###### ERROR: Bluetooth LE Stack not found ############ +# # +# The build target requires a Bluetooth LE stack. # +# $(SOFTDEV_VERSION_LONG) Bluetooth LE stack not found. # +# # +# Please run the download script: # +# # +# bluetooth/download_ble_stack.sh # +# # +####################################################### + +endef + +ifeq ($(shell test ! -e $(SOFTDEV_HEX) && echo -n no),no) + $(error $(STACK_MISSING_ERROR)) +endif diff --git a/ports/nrf/bluetooth/download_ble_stack.sh b/ports/nrf/bluetooth/download_ble_stack.sh new file mode 100755 index 000000000..385dbb451 --- /dev/null +++ b/ports/nrf/bluetooth/download_ble_stack.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +function download_s132_nrf52_2_0_1 +{ + echo "" + echo "####################################" + echo "### Downloading s132_nrf52_2.0.1 ###" + echo "####################################" + echo "" + + mkdir -p "${1}/s132_nrf52_2.0.1" + cd "${1}/s132_nrf52_2.0.1" + wget https://www.nordicsemi.com/eng/nordic/download_resource/51479/6/84640562/95151 + mv 95151 temp.zip + unzip -u temp.zip + rm temp.zip + cd - +} + +function download_s132_nrf52_5_0_0 +{ + echo "" + echo "####################################" + echo "### Downloading s132_nrf52_5.0.0 ###" + echo "####################################" + echo "" + + mkdir -p "${1}/s132_nrf52_5.0.0" + cd "${1}/s132_nrf52_5.0.0" + + wget http://www.nordicsemi.com/eng/nordic/download_resource/58987/11/7198220/116068 + mv 116068 temp.zip + unzip -u temp.zip + rm temp.zip + cd - +} + +function download_s140_nrf52_6_1_0 +{ + echo "" + echo "####################################" + echo "### Downloading s140_nrf52_6.1.0 ###" + echo "####################################" + echo "" + mkdir -p "${1}/s140_nrf52_6.1.0" + cd "${1}/s140_nrf52_6.1.0" + wget https://www.nordicsemi.com/eng/nordic/download_resource/60624/25/88218841/116072 + mv 116072 temp.zip + unzip -u temp.zip + rm temp.zip + cd - +} + +SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +if [ $# -eq 0 ]; then + echo "No Bluetooth LE stack defined, downloading all." + download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" + download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" + download_s140_nrf52_6_1_0 "${SCRIPT_DIR}" +else + case $1 in + "s132_nrf52_2_0_1" ) + download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" ;; + "s132_nrf52_5_0_0" ) + download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" ;; + "s140_nrf52_6_1_0" ) + download_s140_nrf52_6_1_0 "${SCRIPT_DIR}" ;; + esac +fi + +exit 0 diff --git a/ports/nrf/bluetooth/ringbuffer.h b/ports/nrf/bluetooth/ringbuffer.h new file mode 100644 index 000000000..3438b5c9b --- /dev/null +++ b/ports/nrf/bluetooth/ringbuffer.h @@ -0,0 +1,99 @@ +/* The MIT License (MIT) + * + * Copyright (c) 2013 Philip Thrasher + * + * 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. + * Philip Thrasher's Crazy Awesome Ring Buffer Macros! + * + * Below you will find some naughty macros for easy owning and manipulating + * generic ring buffers. Yes, they are slightly evil in readability, but they + * are really fast, and they work great. + * + * Example usage: + * + * #include + * + * // So we can use this in any method, this gives us a typedef + * // named 'intBuffer'. + * ringBuffer_typedef(int, intBuffer); + * + * int main() { + * // Declare vars. + * intBuffer myBuffer; + * + * bufferInit(myBuffer,1024,int); + * + * // We must have the pointer. All of the macros deal with the pointer. + * // (except for init.) + * intBuffer* myBuffer_ptr; + * myBuffer_ptr = &myBuffer; + * + * // Write two values. + * bufferWrite(myBuffer_ptr,37); + * bufferWrite(myBuffer_ptr,72); + * + * // Read a value into a local variable. + * int first; + * bufferRead(myBuffer_ptr,first); + * assert(first == 37); // true + * + * int second; + * bufferRead(myBuffer_ptr,second); + * assert(second == 72); // true + * + * return 0; + * } + * + */ + +#ifndef _ringbuffer_h +#define _ringbuffer_h + +#define ringBuffer_typedef(T, NAME) \ + typedef struct { \ + int size; \ + volatile int start; \ + volatile int end; \ + T* elems; \ + } NAME + +#define bufferInit(BUF, S, T) \ + BUF.size = S+1; \ + BUF.start = 0; \ + BUF.end = 0; \ + BUF.elems = (T*)calloc(BUF.size, sizeof(T)) + + +#define bufferDestroy(BUF) free(BUF->elems) +#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size) +#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size) +#define isBufferEmpty(BUF) (BUF->end == BUF->start) +#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start) + +#define bufferWrite(BUF, ELEM) \ + BUF->elems[BUF->end] = ELEM; \ + BUF->end = (BUF->end + 1) % BUF->size; \ + if (isBufferEmpty(BUF)) { \ + BUF->start = nextStartIndex(BUF); \ + } + +#define bufferRead(BUF, ELEM) \ + ELEM = BUF->elems[BUF->start]; \ + BUF->start = nextStartIndex(BUF); + +#endif diff --git a/ports/nrf/boards/feather_nrf52832/README.md b/ports/nrf/boards/feather_nrf52832/README.md index b5acd6360..ef910509a 100644 --- a/ports/nrf/boards/feather_nrf52832/README.md +++ b/ports/nrf/boards/feather_nrf52832/README.md @@ -18,7 +18,7 @@ You then need to download the SD and Nordic SDK files via: ``` $ cd ports/nrf -$ ./drivers/bluetooth/download_ble_stack.sh +$ ./bluetooth/download_ble_stack.sh ``` ## Installing `adafruit-nrfutil` diff --git a/ports/nrf/boards/feather_nrf52840_express/README.md b/ports/nrf/boards/feather_nrf52840_express/README.md index 5d2177ff3..8d515010f 100644 --- a/ports/nrf/boards/feather_nrf52840_express/README.md +++ b/ports/nrf/boards/feather_nrf52840_express/README.md @@ -33,7 +33,7 @@ You then need to download the SD and Nordic SDK files via: ``` $ cd ports/nrf -$ ./drivers/bluetooth/download_ble_stack.sh +$ ./bluetooth/download_ble_stack.sh ``` ## Installing the Serial Bootloader @@ -198,4 +198,4 @@ Converting to uf2, output size: 392192, start address: 0x26000 Wrote 392192 bytes to build-feather52840-s140/firmware.uf2. ``` -Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. \ No newline at end of file +Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c deleted file mode 100644 index 0b6daf711..000000000 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Glenn Ruben Bakke - * Copyright (c) 2018 Artur Pacholec - * - * 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 -#include - -#include "ble.h" -#include "ble_drv.h" -#include "nrf_nvic.h" -#include "nrf_sdm.h" -#include "py/misc.h" - -nrf_nvic_state_t nrf_nvic_state = { 0 }; - -__attribute__((aligned(4))) -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; - -typedef struct event_handler { - struct event_handler *next; - void *param; - ble_drv_evt_handler_t func; -} event_handler_t; - -static event_handler_t *m_event_handlers; - -void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { - event_handler_t *handler = m_new_ll(event_handler_t, 1); - handler->next = NULL; - handler->param = param; - handler->func = func; - - if (m_event_handlers == NULL) { - m_event_handlers = handler; - return; - } - - event_handler_t *it = m_event_handlers; - while (it->next != NULL) { - if ((it->func == func) && (it->param == param)) { - m_free(handler); - return; - } - - it = it->next; - } - - it->next = handler; -} - -void SD_EVT_IRQHandler(void) { - uint32_t evt_id; - while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { -// sd_evt_handler(evt_id); - } - - while (1) { - uint16_t evt_len = sizeof(m_ble_evt_buf); - const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); - if (err_code != NRF_SUCCESS) { - if (err_code == NRF_ERROR_DATA_SIZE) { - printf("NRF_ERROR_DATA_SIZE\n"); - } - - break; - } - - event_handler_t *it = m_event_handlers; - while (it != NULL) { - it->func((ble_evt_t *)m_ble_evt_buf, it->param); - it = it->next; - } - } -} diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h deleted file mode 100644 index 426354a19..000000000 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Glenn Ruben Bakke - * Copyright (c) 2018 Artur Pacholec - * - * 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. - */ - -#ifndef BLUETOOTH_LE_DRIVER_H__ -#define BLUETOOTH_LE_DRIVER_H__ - -#include "ble.h" - -#if (BLUETOOTH_SD == 132) && (BLE_API_VERSION == 2) -#define NRF52 -#endif - -#define MAX_TX_IN_PROGRESS 10 - -#ifndef BLE_GATT_ATT_MTU_DEFAULT - #define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT -#endif - -#define BLE_CONN_CFG_TAG_CUSTOM 1 - -#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) -#define UNIT_0_625_MS (625) -#define UNIT_10_MS (10000) - -typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); - -void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); - -#endif // BLUETOOTH_LE_DRIVER_H__ diff --git a/ports/nrf/drivers/bluetooth/ble_uart.c b/ports/nrf/drivers/bluetooth/ble_uart.c deleted file mode 100644 index b1d54eefa..000000000 --- a/ports/nrf/drivers/bluetooth/ble_uart.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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. - */ - -#if BLUETOOTH_SD - -#include -#include "ble_uart.h" -#include "ringbuffer.h" -#include "py/mphal.h" -#include "lib/utils/interrupt_char.h" - -#if MICROPY_PY_BLE_NUS - -static bleio_uuid_obj_t uuid_obj_service = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x01, 0x00} -}; - -static bleio_uuid_obj_t uuid_obj_char_tx = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x03, 0x00} -}; - -static bleio_uuid_obj_t uuid_obj_char_rx = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x02, 0x00} -}; - -static ubluepy_service_obj_t ble_uart_service = { - .base.type = &ubluepy_service_type, - .p_uuid = &uuid_obj_service, - .type = UBLUEPY_SERVICE_PRIMARY -}; - -static ubluepy_characteristic_obj_t ble_uart_char_rx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_rx, - .props = UBLUEPY_PROP_WRITE | UBLUEPY_PROP_WRITE_WO_RESP, - .attrs = 0, -}; - -static ubluepy_characteristic_obj_t ble_uart_char_tx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_tx, - .props = UBLUEPY_PROP_NOTIFY, - .attrs = UBLUEPY_ATTR_CCCD, -}; - -static ubluepy_peripheral_obj_t ble_uart_peripheral = { - .base.type = &ubluepy_peripheral_type, - .conn_handle = 0xFFFF, -}; - -static volatile bool m_cccd_enabled; -static volatile bool m_connected; - -ringBuffer_typedef(uint8_t, ringbuffer_t); - -static ringbuffer_t m_rx_ring_buffer; -static ringbuffer_t * mp_rx_ring_buffer = &m_rx_ring_buffer; -static uint8_t m_rx_ring_buffer_data[128]; - -static ubluepy_advertise_data_t m_adv_data_uart_service; - -#if BLUETOOTH_WEBBLUETOOTH_REPL -static ubluepy_advertise_data_t m_adv_data_eddystone_url; -#endif // BLUETOOTH_WEBBLUETOOTH_REPL - -int mp_hal_stdin_rx_chr(void) { - while (isBufferEmpty(mp_rx_ring_buffer)) { - ; - } - - uint8_t byte; - bufferRead(mp_rx_ring_buffer, byte); - return (int)byte; -} - -bool mp_hal_stdin_any(void) { - return !isBufferEmpty(mp_rx_ring_buffer); -} - -void mp_hal_stdout_tx_strn(const char *str, size_t len) { - uint8_t *buf = (uint8_t *)str; - size_t send_len; - - while (len > 0) { - if (len >= 20) { - send_len = 20; // (GATT_MTU_SIZE_DEFAULT - 3) - } else { - send_len = len; - } - - ubluepy_characteristic_obj_t * p_char = &ble_uart_char_tx; - - ble_drv_attr_s_notify(p_char->p_service->p_periph->conn_handle, - p_char->handle, - send_len, - buf); - - len -= send_len; - buf += send_len; - } -} - -void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) { - mp_hal_stdout_tx_strn(str, len); -} - -STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - - if (event_id == 16) { // connect event - self->conn_handle = conn_handle; - m_connected = true; - } else if (event_id == 17) { // disconnect event - self->conn_handle = 0xFFFF; // invalid connection handle - m_connected = false; - ble_uart_advertise(); - } -} - -STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - (void)self; - - if (event_id == 80) { // gatts write - if (ble_uart_char_tx.cccd_handle == attr_handle) { - m_cccd_enabled = true; - } else if (ble_uart_char_rx.handle == attr_handle) { - for (uint16_t i = 0; i < length; i++) { - #if MICROPY_KBD_EXCEPTION - if (data[i] == mp_interrupt_char) { - mp_keyboard_interrupt(); - } else - #endif - { - bufferWrite(mp_rx_ring_buffer, data[i]); - } - } - } - } -} - -void ble_uart_init0(void) { - uint8_t base_uuid[] = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}; - uint8_t uuid_vs_idx; - - (void)ble_drv_uuid_add_vs(base_uuid, &uuid_vs_idx); - - uuid_obj_service.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_tx.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_rx.uuid_vs_idx = uuid_vs_idx; - - (void)ble_drv_service_add(&ble_uart_service); - ble_uart_service.char_list = mp_obj_new_list(0, NULL); - - // add TX characteristic - ble_uart_char_tx.service_handle = ble_uart_service.handle; - bool retval = ble_drv_characteristic_add(&ble_uart_char_tx); - if (retval) { - ble_uart_char_tx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx)); - - // add RX characteristic - ble_uart_char_rx.service_handle = ble_uart_service.handle; - retval = ble_drv_characteristic_add(&ble_uart_char_rx); - if (retval) { - ble_uart_char_rx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx)); - - // setup the peripheral - ble_uart_peripheral.service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(ble_uart_peripheral.service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - ble_uart_service.p_periph = &ble_uart_peripheral; - - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gap_event_handler); - ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gatts_event_handler); - - ble_uart_peripheral.conn_handle = 0xFFFF; - - char device_name[] = "mpus"; - - mp_obj_t service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(service_list, &num_services, &services); - - m_adv_data_uart_service.p_services = services; - m_adv_data_uart_service.num_of_services = num_services; - m_adv_data_uart_service.p_device_name = (uint8_t *)device_name; - m_adv_data_uart_service.device_name_len = strlen(device_name); - m_adv_data_uart_service.connectable = true; - m_adv_data_uart_service.p_data = NULL; - -#if BLUETOOTH_WEBBLUETOOTH_REPL - // for now point eddystone URL to https://goo.gl/x46FES => https://glennrub.github.io/webbluetooth/micropython/repl/ - static uint8_t eddystone_url_data[27] = {0x2, 0x1, 0x6, - 0x3, 0x3, 0xaa, 0xfe, - 19, 0x16, 0xaa, 0xfe, 0x10, 0xee, 0x3, 'g', 'o', 'o', '.', 'g', 'l', '/', 'x', '4', '6', 'F', 'E', 'S'}; - // eddystone url adv data - m_adv_data_eddystone_url.p_data = eddystone_url_data; - m_adv_data_eddystone_url.data_len = sizeof(eddystone_url_data); - m_adv_data_eddystone_url.connectable = false; -#endif - - m_cccd_enabled = false; - - // initialize ring buffer - m_rx_ring_buffer.size = sizeof(m_rx_ring_buffer_data) + 1; - m_rx_ring_buffer.start = 0; - m_rx_ring_buffer.end = 0; - m_rx_ring_buffer.elems = m_rx_ring_buffer_data; - - m_connected = false; - - ble_uart_advertise(); -} - -void ble_uart_advertise(void) { -#if BLUETOOTH_WEBBLUETOOTH_REPL - while (!m_connected) { - (void)ble_drv_advertise_data(&m_adv_data_uart_service); - mp_hal_delay_ms(500); - (void)ble_drv_advertise_data(&m_adv_data_eddystone_url); - mp_hal_delay_ms(500); - } - - ble_drv_advertise_stop(); -#else - (void)ble_drv_advertise_data(&m_adv_data_uart_service); -#endif // BLUETOOTH_WEBBLUETOOTH_REPL -} - -bool ble_uart_connected(void) { - return (m_connected); -} - -bool ble_uart_enabled(void) { - return (m_cccd_enabled); -} - -#endif // MICROPY_PY_BLE_NUS - -#endif // BLUETOOTH_SD diff --git a/ports/nrf/drivers/bluetooth/ble_uart.h b/ports/nrf/drivers/bluetooth/ble_uart.h deleted file mode 100644 index b57a75229..000000000 --- a/ports/nrf/drivers/bluetooth/ble_uart.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * 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. - */ - -#ifndef BLUETOOTH_LE_UART_H__ -#define BLUETOOTH_LE_UART_H__ - -#include - -#include "ble_drv.h" - -void ble_uart_init0(void); -void ble_uart_advertise(void); -bool ble_uart_connected(void); -bool ble_uart_enabled(void); - -#endif // BLUETOOTH_LE_UART_H__ diff --git a/ports/nrf/drivers/bluetooth/bluetooth_common.mk b/ports/nrf/drivers/bluetooth/bluetooth_common.mk deleted file mode 100644 index 81e50e333..000000000 --- a/ports/nrf/drivers/bluetooth/bluetooth_common.mk +++ /dev/null @@ -1,43 +0,0 @@ -ifeq ($(SD), s132) - CFLAGS += -DBLUETOOTH_SD=132 - -ifeq ($(SOFTDEV_VERSION), 2.0.1) - CFLAGS += -DBLE_API_VERSION=2 -else ifeq ($(SOFTDEV_VERSION), 5.0.0) - CFLAGS += -DBLE_API_VERSION=4 -endif -else ifeq ($(SD), s140) - CFLAGS += -DBLUETOOTH_SD=140 - CFLAGS += -DBLE_API_VERSION=4 -else -$(error Incorrect softdevice set flag) -endif - -CFLAGS += -DBLUETOOTH_SD_DEBUG=1 - -INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include -INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) - -SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex -SOFTDEV_HEX_PATH = drivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) -SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME) - -define STACK_MISSING_ERROR - - -###### ERROR: Bluetooth LE Stack not found ############ -# # -# The build target requires a Bluetooth LE stack. # -# $(SOFTDEV_VERSION_LONG) Bluetooth LE stack not found. # -# # -# Please run the download script: # -# # -# drivers/bluetooth/download_ble_stack.sh # -# # -####################################################### - -endef - -ifeq ($(shell test ! -e $(SOFTDEV_HEX) && echo -n no),no) - $(error $(STACK_MISSING_ERROR)) -endif diff --git a/ports/nrf/drivers/bluetooth/download_ble_stack.sh b/ports/nrf/drivers/bluetooth/download_ble_stack.sh deleted file mode 100755 index 385dbb451..000000000 --- a/ports/nrf/drivers/bluetooth/download_ble_stack.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash - -function download_s132_nrf52_2_0_1 -{ - echo "" - echo "####################################" - echo "### Downloading s132_nrf52_2.0.1 ###" - echo "####################################" - echo "" - - mkdir -p "${1}/s132_nrf52_2.0.1" - cd "${1}/s132_nrf52_2.0.1" - wget https://www.nordicsemi.com/eng/nordic/download_resource/51479/6/84640562/95151 - mv 95151 temp.zip - unzip -u temp.zip - rm temp.zip - cd - -} - -function download_s132_nrf52_5_0_0 -{ - echo "" - echo "####################################" - echo "### Downloading s132_nrf52_5.0.0 ###" - echo "####################################" - echo "" - - mkdir -p "${1}/s132_nrf52_5.0.0" - cd "${1}/s132_nrf52_5.0.0" - - wget http://www.nordicsemi.com/eng/nordic/download_resource/58987/11/7198220/116068 - mv 116068 temp.zip - unzip -u temp.zip - rm temp.zip - cd - -} - -function download_s140_nrf52_6_1_0 -{ - echo "" - echo "####################################" - echo "### Downloading s140_nrf52_6.1.0 ###" - echo "####################################" - echo "" - mkdir -p "${1}/s140_nrf52_6.1.0" - cd "${1}/s140_nrf52_6.1.0" - wget https://www.nordicsemi.com/eng/nordic/download_resource/60624/25/88218841/116072 - mv 116072 temp.zip - unzip -u temp.zip - rm temp.zip - cd - -} - -SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -if [ $# -eq 0 ]; then - echo "No Bluetooth LE stack defined, downloading all." - download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" - download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" - download_s140_nrf52_6_1_0 "${SCRIPT_DIR}" -else - case $1 in - "s132_nrf52_2_0_1" ) - download_s132_nrf52_2_0_1 "${SCRIPT_DIR}" ;; - "s132_nrf52_5_0_0" ) - download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" ;; - "s140_nrf52_6_1_0" ) - download_s140_nrf52_6_1_0 "${SCRIPT_DIR}" ;; - esac -fi - -exit 0 diff --git a/ports/nrf/drivers/bluetooth/ringbuffer.h b/ports/nrf/drivers/bluetooth/ringbuffer.h deleted file mode 100644 index 3438b5c9b..000000000 --- a/ports/nrf/drivers/bluetooth/ringbuffer.h +++ /dev/null @@ -1,99 +0,0 @@ -/* The MIT License (MIT) - * - * Copyright (c) 2013 Philip Thrasher - * - * 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. - * Philip Thrasher's Crazy Awesome Ring Buffer Macros! - * - * Below you will find some naughty macros for easy owning and manipulating - * generic ring buffers. Yes, they are slightly evil in readability, but they - * are really fast, and they work great. - * - * Example usage: - * - * #include - * - * // So we can use this in any method, this gives us a typedef - * // named 'intBuffer'. - * ringBuffer_typedef(int, intBuffer); - * - * int main() { - * // Declare vars. - * intBuffer myBuffer; - * - * bufferInit(myBuffer,1024,int); - * - * // We must have the pointer. All of the macros deal with the pointer. - * // (except for init.) - * intBuffer* myBuffer_ptr; - * myBuffer_ptr = &myBuffer; - * - * // Write two values. - * bufferWrite(myBuffer_ptr,37); - * bufferWrite(myBuffer_ptr,72); - * - * // Read a value into a local variable. - * int first; - * bufferRead(myBuffer_ptr,first); - * assert(first == 37); // true - * - * int second; - * bufferRead(myBuffer_ptr,second); - * assert(second == 72); // true - * - * return 0; - * } - * - */ - -#ifndef _ringbuffer_h -#define _ringbuffer_h - -#define ringBuffer_typedef(T, NAME) \ - typedef struct { \ - int size; \ - volatile int start; \ - volatile int end; \ - T* elems; \ - } NAME - -#define bufferInit(BUF, S, T) \ - BUF.size = S+1; \ - BUF.start = 0; \ - BUF.end = 0; \ - BUF.elems = (T*)calloc(BUF.size, sizeof(T)) - - -#define bufferDestroy(BUF) free(BUF->elems) -#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size) -#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size) -#define isBufferEmpty(BUF) (BUF->end == BUF->start) -#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start) - -#define bufferWrite(BUF, ELEM) \ - BUF->elems[BUF->end] = ELEM; \ - BUF->end = (BUF->end + 1) % BUF->size; \ - if (isBufferEmpty(BUF)) { \ - BUF->start = nextStartIndex(BUF); \ - } - -#define bufferRead(BUF, ELEM) \ - ELEM = BUF->elems[BUF->start]; \ - BUF->start = nextStartIndex(BUF); - -#endif -- cgit v1.2.3 From cf7931600266864e1797271783aadafdc3aa72bb Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 23 Jul 2018 23:43:24 +0200 Subject: nrf: Fix ble uart using the new API --- ports/nrf/bluetooth/ble_uart.c | 333 +++++++++++++++------------------------ ports/nrf/bluetooth/ble_uart.h | 13 +- ports/nrf/bluetooth/ringbuffer.h | 20 +-- ports/nrf/mpconfigport.h | 1 - ports/nrf/mphalport.c | 3 +- ports/nrf/supervisor/serial.c | 34 ++-- 6 files changed, 169 insertions(+), 235 deletions(-) diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c index b1d54eefa..7faaafb0e 100644 --- a/ports/nrf/bluetooth/ble_uart.c +++ b/ports/nrf/bluetooth/ble_uart.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,252 +25,172 @@ * THE SOFTWARE. */ -#if BLUETOOTH_SD - #include + +#include "ble.h" #include "ble_uart.h" #include "ringbuffer.h" #include "py/mphal.h" +#include "py/runtime.h" #include "lib/utils/interrupt_char.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" -#if MICROPY_PY_BLE_NUS +#if (MICROPY_PY_BLE_NUS == 1) -static bleio_uuid_obj_t uuid_obj_service = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x01, 0x00} -}; +static const char default_name[] = "CP-REPL"; // max 8 chars or uuid won't fit in adv data +static const char NUS_UUID[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; -static bleio_uuid_obj_t uuid_obj_char_tx = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x03, 0x00} -}; +#define NUS_RX_UUID 0x0002 +#define NUS_TX_UUID 0x0003 +#define BUFFER_SIZE 128 -static bleio_uuid_obj_t uuid_obj_char_rx = { - .base.type = &bleio_uuid_type, - .type = UUID_128_BIT, - .value = {0x02, 0x00} -}; +ringBuffer_typedef(uint8_t, ringbuffer_t); -static ubluepy_service_obj_t ble_uart_service = { - .base.type = &ubluepy_service_type, - .p_uuid = &uuid_obj_service, - .type = UBLUEPY_SERVICE_PRIMARY -}; +static bleio_device_obj_t m_device; +static bleio_service_obj_t *m_nus; +static bleio_characteristic_obj_t *m_tx_chara; +static bleio_characteristic_obj_t *m_rx_chara; -static ubluepy_characteristic_obj_t ble_uart_char_rx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_rx, - .props = UBLUEPY_PROP_WRITE | UBLUEPY_PROP_WRITE_WO_RESP, - .attrs = 0, -}; +static volatile bool m_cccd_enabled; -static ubluepy_characteristic_obj_t ble_uart_char_tx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_tx, - .props = UBLUEPY_PROP_NOTIFY, - .attrs = UBLUEPY_ATTR_CCCD, +static uint8_t m_rx_ring_buffer_data[BUFFER_SIZE]; +static ringbuffer_t m_rx_ring_buffer = { + .size = sizeof(m_rx_ring_buffer_data) + 1, + .elems = m_rx_ring_buffer_data, }; -static ubluepy_peripheral_obj_t ble_uart_peripheral = { - .base.type = &ubluepy_peripheral_type, - .conn_handle = 0xFFFF, -}; +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_DISCONNECTED: + { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + break; + } -static volatile bool m_cccd_enabled; -static volatile bool m_connected; + case BLE_GATTS_EVT_WRITE: + { + ble_gatts_evt_write_t *write = &ble_evt->evt.gatts_evt.params.write; + + if (write->handle == m_tx_chara->cccd_handle) { + m_cccd_enabled = true; + } else if (write->handle == m_rx_chara->handle) { + for (size_t i = 0; i < write->len; ++i) { +#if MICROPY_KBD_EXCEPTION + if (write->data[i] == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else +#endif + { + bufferWrite(&m_rx_ring_buffer, write->data[i]); + } + } + } + } + } +} -ringBuffer_typedef(uint8_t, ringbuffer_t); +void ble_uart_init(void) { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + m_device.base.type = &bleio_device_type; + m_device.service_list = mp_obj_new_list(0, NULL); + m_device.notif_handler = mp_const_none; + m_device.conn_handler = mp_const_none; + m_device.conn_handle = 0xFFFF; + m_device.is_peripheral = true; + m_device.name = mp_obj_new_str(default_name, strlen(default_name), false); + common_hal_bleio_adapter_get_address(&m_device.address); + + mp_obj_t nus_uuid_str = mp_obj_new_str(NUS_UUID, strlen(NUS_UUID), false); + mp_obj_t nus_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &nus_uuid_str); + mp_obj_t nus_obj = bleio_service_type.make_new(&bleio_service_type, 1, 0, &nus_uuid_obj); + m_nus = MP_OBJ_TO_PTR(nus_obj); + mp_call_function_1(mp_load_attr(device_obj, qstr_from_str("add_service")), nus_obj); + + mp_obj_t tx_uuid_int = mp_obj_new_int(NUS_TX_UUID); + mp_obj_t tx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &tx_uuid_int); + mp_obj_t tx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &tx_uuid_obj); + m_tx_chara = MP_OBJ_TO_PTR(tx_obj); + m_tx_chara->uuid->type = UUID_TYPE_128BIT; + m_tx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_tx_chara->props.notify = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), tx_obj); + + mp_obj_t rx_uuid_int = mp_obj_new_int(NUS_RX_UUID); + mp_obj_t rx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &rx_uuid_int); + mp_obj_t rx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &rx_uuid_obj); + m_rx_chara = MP_OBJ_TO_PTR(rx_obj); + m_rx_chara->uuid->type = UUID_TYPE_128BIT; + m_rx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_rx_chara->props.write = true; + m_rx_chara->props.write_wo_resp = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), rx_obj); + + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + + ble_drv_add_event_handler(on_ble_evt, &m_device); -static ringbuffer_t m_rx_ring_buffer; -static ringbuffer_t * mp_rx_ring_buffer = &m_rx_ring_buffer; -static uint8_t m_rx_ring_buffer_data[128]; + m_cccd_enabled = false; -static ubluepy_advertise_data_t m_adv_data_uart_service; + while (!m_cccd_enabled) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } +} -#if BLUETOOTH_WEBBLUETOOTH_REPL -static ubluepy_advertise_data_t m_adv_data_eddystone_url; -#endif // BLUETOOTH_WEBBLUETOOTH_REPL +bool ble_uart_connected(void) { + return (m_device.conn_handle != BLE_CONN_HANDLE_INVALID); +} -int mp_hal_stdin_rx_chr(void) { - while (isBufferEmpty(mp_rx_ring_buffer)) { - ; +char ble_uart_rx_chr(void) { + while (isBufferEmpty(&m_rx_ring_buffer)) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif } uint8_t byte; - bufferRead(mp_rx_ring_buffer, byte); + bufferRead(&m_rx_ring_buffer, byte); return (int)byte; } -bool mp_hal_stdin_any(void) { - return !isBufferEmpty(mp_rx_ring_buffer); +bool ble_uart_stdin_any(void) { + return !isBufferEmpty(&m_rx_ring_buffer); +} + +void ble_uart_stdout_tx_str(const char *text) { + mp_hal_stdout_tx_strn(text, strlen(text)); +} + +int mp_hal_stdin_rx_chr(void) { + return ble_uart_rx_chr(); } void mp_hal_stdout_tx_strn(const char *str, size_t len) { - uint8_t *buf = (uint8_t *)str; size_t send_len; while (len > 0) { - if (len >= 20) { - send_len = 20; // (GATT_MTU_SIZE_DEFAULT - 3) + if (len >= BLE_GATT_ATT_MTU_DEFAULT - 3) { + send_len = (BLE_GATT_ATT_MTU_DEFAULT - 3); } else { send_len = len; } - ubluepy_characteristic_obj_t * p_char = &ble_uart_char_tx; + mp_buffer_info_t bufinfo = { + .buf = (uint8_t*)str, + .len = send_len, + }; - ble_drv_attr_s_notify(p_char->p_service->p_periph->conn_handle, - p_char->handle, - send_len, - buf); + common_hal_bleio_characteristic_write_value(m_tx_chara, &bufinfo); len -= send_len; - buf += send_len; + str += send_len; } } -void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) { - mp_hal_stdout_tx_strn(str, len); -} - -STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - - if (event_id == 16) { // connect event - self->conn_handle = conn_handle; - m_connected = true; - } else if (event_id == 17) { // disconnect event - self->conn_handle = 0xFFFF; // invalid connection handle - m_connected = false; - ble_uart_advertise(); - } -} - -STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - (void)self; - - if (event_id == 80) { // gatts write - if (ble_uart_char_tx.cccd_handle == attr_handle) { - m_cccd_enabled = true; - } else if (ble_uart_char_rx.handle == attr_handle) { - for (uint16_t i = 0; i < length; i++) { - #if MICROPY_KBD_EXCEPTION - if (data[i] == mp_interrupt_char) { - mp_keyboard_interrupt(); - } else - #endif - { - bufferWrite(mp_rx_ring_buffer, data[i]); - } - } - } - } -} - -void ble_uart_init0(void) { - uint8_t base_uuid[] = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}; - uint8_t uuid_vs_idx; - - (void)ble_drv_uuid_add_vs(base_uuid, &uuid_vs_idx); - - uuid_obj_service.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_tx.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_rx.uuid_vs_idx = uuid_vs_idx; - - (void)ble_drv_service_add(&ble_uart_service); - ble_uart_service.char_list = mp_obj_new_list(0, NULL); - - // add TX characteristic - ble_uart_char_tx.service_handle = ble_uart_service.handle; - bool retval = ble_drv_characteristic_add(&ble_uart_char_tx); - if (retval) { - ble_uart_char_tx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx)); - - // add RX characteristic - ble_uart_char_rx.service_handle = ble_uart_service.handle; - retval = ble_drv_characteristic_add(&ble_uart_char_rx); - if (retval) { - ble_uart_char_rx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx)); - - // setup the peripheral - ble_uart_peripheral.service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(ble_uart_peripheral.service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - ble_uart_service.p_periph = &ble_uart_peripheral; - - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gap_event_handler); - ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gatts_event_handler); - - ble_uart_peripheral.conn_handle = 0xFFFF; - - char device_name[] = "mpus"; - - mp_obj_t service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(service_list, &num_services, &services); - - m_adv_data_uart_service.p_services = services; - m_adv_data_uart_service.num_of_services = num_services; - m_adv_data_uart_service.p_device_name = (uint8_t *)device_name; - m_adv_data_uart_service.device_name_len = strlen(device_name); - m_adv_data_uart_service.connectable = true; - m_adv_data_uart_service.p_data = NULL; - -#if BLUETOOTH_WEBBLUETOOTH_REPL - // for now point eddystone URL to https://goo.gl/x46FES => https://glennrub.github.io/webbluetooth/micropython/repl/ - static uint8_t eddystone_url_data[27] = {0x2, 0x1, 0x6, - 0x3, 0x3, 0xaa, 0xfe, - 19, 0x16, 0xaa, 0xfe, 0x10, 0xee, 0x3, 'g', 'o', 'o', '.', 'g', 'l', '/', 'x', '4', '6', 'F', 'E', 'S'}; - // eddystone url adv data - m_adv_data_eddystone_url.p_data = eddystone_url_data; - m_adv_data_eddystone_url.data_len = sizeof(eddystone_url_data); - m_adv_data_eddystone_url.connectable = false; -#endif - - m_cccd_enabled = false; - - // initialize ring buffer - m_rx_ring_buffer.size = sizeof(m_rx_ring_buffer_data) + 1; - m_rx_ring_buffer.start = 0; - m_rx_ring_buffer.end = 0; - m_rx_ring_buffer.elems = m_rx_ring_buffer_data; - - m_connected = false; - - ble_uart_advertise(); -} - -void ble_uart_advertise(void) { -#if BLUETOOTH_WEBBLUETOOTH_REPL - while (!m_connected) { - (void)ble_drv_advertise_data(&m_adv_data_uart_service); - mp_hal_delay_ms(500); - (void)ble_drv_advertise_data(&m_adv_data_eddystone_url); - mp_hal_delay_ms(500); - } - - ble_drv_advertise_stop(); -#else - (void)ble_drv_advertise_data(&m_adv_data_uart_service); -#endif // BLUETOOTH_WEBBLUETOOTH_REPL -} - -bool ble_uart_connected(void) { - return (m_connected); -} - -bool ble_uart_enabled(void) { - return (m_cccd_enabled); -} - #endif // MICROPY_PY_BLE_NUS - -#endif // BLUETOOTH_SD diff --git a/ports/nrf/bluetooth/ble_uart.h b/ports/nrf/bluetooth/ble_uart.h index b57a75229..d86e6293a 100644 --- a/ports/nrf/bluetooth/ble_uart.h +++ b/ports/nrf/bluetooth/ble_uart.h @@ -24,16 +24,17 @@ * THE SOFTWARE. */ -#ifndef BLUETOOTH_LE_UART_H__ -#define BLUETOOTH_LE_UART_H__ +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H #include #include "ble_drv.h" -void ble_uart_init0(void); -void ble_uart_advertise(void); +void ble_uart_init(void); bool ble_uart_connected(void); -bool ble_uart_enabled(void); +char ble_uart_rx_chr(void); +bool ble_uart_stdin_any(void); +void ble_uart_stdout_tx_str(const char *text); -#endif // BLUETOOTH_LE_UART_H__ +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H diff --git a/ports/nrf/bluetooth/ringbuffer.h b/ports/nrf/bluetooth/ringbuffer.h index 3438b5c9b..9a06e7ccc 100644 --- a/ports/nrf/bluetooth/ringbuffer.h +++ b/ports/nrf/bluetooth/ringbuffer.h @@ -79,21 +79,21 @@ BUF.elems = (T*)calloc(BUF.size, sizeof(T)) -#define bufferDestroy(BUF) free(BUF->elems) -#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size) -#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size) -#define isBufferEmpty(BUF) (BUF->end == BUF->start) -#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start) +#define bufferDestroy(BUF) free((BUF)->elems) +#define nextStartIndex(BUF) (((BUF)->start + 1) % (BUF)->size) +#define nextEndIndex(BUF) (((BUF)->end + 1) % (BUF)->size) +#define isBufferEmpty(BUF) ((BUF)->end == (BUF)->start) +#define isBufferFull(BUF) (nextEndIndex(BUF) == (BUF)->start) #define bufferWrite(BUF, ELEM) \ - BUF->elems[BUF->end] = ELEM; \ - BUF->end = (BUF->end + 1) % BUF->size; \ + (BUF)->elems[(BUF)->end] = ELEM; \ + (BUF)->end = ((BUF)->end + 1) % (BUF)->size; \ if (isBufferEmpty(BUF)) { \ - BUF->start = nextStartIndex(BUF); \ + (BUF)->start = nextStartIndex(BUF); \ } #define bufferRead(BUF, ELEM) \ - ELEM = BUF->elems[BUF->start]; \ - BUF->start = nextStartIndex(BUF); + ELEM = (BUF)->elems[(BUF)->start]; \ + (BUF)->start = nextStartIndex(BUF); #endif diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 62a041ae9..8b193fb59 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -131,7 +131,6 @@ #if BLUETOOTH_SD #define MICROPY_PY_BLEIO (1) #define MICROPY_PY_BLE_NUS (0) - #define BLUETOOTH_WEBBLUETOOTH_REPL (0) #else #ifndef MICROPY_PY_BLEIO #define MICROPY_PY_BLEIO (0) diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 27ed57bf3..e9a8722c6 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -109,8 +109,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { #endif // USB -#endif // NUS - +#endif // MICROPY_PY_BLE_NUS /*------------------------------------------------------------------*/ /* delay diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index cfbcc4b31..c7744fd79 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -26,25 +26,41 @@ #include "py/mphal.h" -#if MICROPY_PY_BLE_NUS +#if (MICROPY_PY_BLE_NUS == 1) #include "ble_uart.h" #else #include "nrf_gpio.h" #include "nrfx_uarte.h" #endif -#if !defined(NRF52840_XXAA) +#if (MICROPY_PY_BLE_NUS == 1) + +void serial_init(void) { + ble_uart_init(); +} + +bool serial_connected(void) { + return ble_uart_connected(); +} + +char serial_read(void) { + return (char) ble_uart_rx_chr(); +} + +bool serial_bytes_available(void) { + return ble_uart_stdin_any(); +} + +void serial_write(const char *text) { + ble_uart_stdout_tx_str(text); +} + +#elif !defined(NRF52840_XXAA) uint8_t serial_received_char; nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0); void serial_init(void) { -#if MICROPY_PY_BLE_NUS - ble_uart_init0(); - while (!ble_uart_enabled()) { - ; - } -#else nrfx_uarte_config_t config = { .pseltxd = MICROPY_HW_UART_TX, .pselrxd = MICROPY_HW_UART_RX, @@ -66,7 +82,6 @@ void serial_init(void) { // enabled receiving nrf_uarte_task_trigger(serial_instance.p_reg, NRF_UARTE_TASK_STARTRX); -#endif } bool serial_connected(void) { @@ -93,7 +108,6 @@ void serial_init(void) { // usb is already initialized in board_init() } - bool serial_connected(void) { return tud_cdc_connected(); } -- cgit v1.2.3 From c7b42d80b3df38048b2269c5eae55e318204e564 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 23 Jul 2018 23:45:16 +0200 Subject: bleio: A bit of cleanup --- ports/nrf/bluetooth/ble_drv.h | 6 +++--- ports/nrf/common-hal/bleio/Characteristic.c | 23 +++++++++-------------- ports/nrf/common-hal/bleio/Device.c | 2 +- shared-bindings/bleio/Device.c | 2 ++ shared-bindings/bleio/Service.c | 2 ++ 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h index 426354a19..0443b41b8 100644 --- a/ports/nrf/bluetooth/ble_drv.h +++ b/ports/nrf/bluetooth/ble_drv.h @@ -25,8 +25,8 @@ * THE SOFTWARE. */ -#ifndef BLUETOOTH_LE_DRIVER_H__ -#define BLUETOOTH_LE_DRIVER_H__ +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H #include "ble.h" @@ -50,4 +50,4 @@ typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); -#endif // BLUETOOTH_LE_DRIVER_H__ +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index 040cacc3f..a370d29a7 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -36,7 +36,6 @@ static volatile bleio_characteristic_obj_t *m_read_characteristic; static volatile uint8_t m_tx_in_progress; static nrf_mutex_t *m_write_mutex; -//static volatile bool m_write_done; STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { bleio_device_obj_t *device = characteristic->service->device; @@ -101,23 +100,19 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { bleio_device_obj_t *device = characteristic->service->device; - uint16_t conn_handle = device->conn_handle; uint32_t err_code; - ble_gattc_write_params_t write_params; - write_params.write_op = BLE_GATT_OP_WRITE_REQ; + ble_gattc_write_params_t write_params = { + .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL, + .write_op = BLE_GATT_OP_WRITE_REQ, + .handle = characteristic->handle, + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; if (characteristic->props.write_wo_resp) { write_params.write_op = BLE_GATT_OP_WRITE_CMD; - } - - write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; - write_params.handle = characteristic->handle; - write_params.offset = 0; - write_params.len = bufinfo->len; - write_params.p_value = bufinfo->buf; - if (write_params.write_op == BLE_GATT_OP_WRITE_CMD) { err_code = sd_mutex_acquire(m_write_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, @@ -125,8 +120,8 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in } } - err_code = sd_ble_gattc_write(conn_handle, &write_params); - if (err_code != 0) { + err_code = sd_ble_gattc_write(device->conn_handle, &write_params); + if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Failed to write attribute value, status: 0x%08lX", err_code)); } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 195b6cd32..8e52b2fbc 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -297,7 +297,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o m_discovery_successful = false; uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range); - if (err_code != 0) { + if (err_code != NRF_SUCCESS) { return false; } diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 8c7cef95f..ec7121f54 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -144,6 +144,8 @@ //| Disconnects from the remote device. //| This method can only be called for Peripheral devices. //| + +// TODO: Add unique MAC address part to name static const char default_name[] = "CIRCUITPY"; STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index a2f9b9899..3a4aa4737 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -115,6 +115,8 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char characteristic->service_handle = self->handle; + // TODO: If service is 128b then update Chara UUID to be 128b too + common_hal_bleio_service_add_characteristic(self, characteristic); mp_obj_list_append(self->char_list, characteristic); -- cgit v1.2.3 From b5e5805bb408ca3bb5975d8fad21070dbf4d51e9 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 23 Jul 2018 23:52:09 +0200 Subject: bleio: Remove redundant struct field --- ports/nrf/common-hal/bleio/Device.c | 2 -- ports/nrf/common-hal/bleio/Service.c | 3 +-- shared-bindings/bleio/Service.c | 4 ++-- shared-module/bleio/Characteristic.h | 1 - 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index 8e52b2fbc..fd772c04d 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -376,8 +376,6 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio characteristic->props.write = gattc_char->char_props.write; characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; characteristic->handle = gattc_char->handle_value; - - characteristic->service_handle = m_char_discovery_service->handle; characteristic->service = m_char_discovery_service; mp_obj_list_append(m_char_discovery_service->char_list, MP_OBJ_FROM_PTR(characteristic)); diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 9e376b333..93588d156 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -101,7 +101,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei ble_gatts_char_handles_t handles; uint32_t err_code; - err_code = sd_ble_gatts_characteristic_add(characteristic->service_handle, &char_md, &attr_char_value, &handles); + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Failed to add characteristic, status: 0x%08lX", err_code)); @@ -111,5 +111,4 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei characteristic->cccd_handle = handles.cccd_handle; characteristic->sccd_handle = handles.sccd_handle; characteristic->handle = handles.value_handle; - characteristic->service = self; } diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 3a4aa4737..94d245d7f 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -113,12 +113,12 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - characteristic->service_handle = self->handle; - // TODO: If service is 128b then update Chara UUID to be 128b too common_hal_bleio_service_add_characteristic(self, characteristic); + characteristic->service = self; + mp_obj_list_append(self->char_list, characteristic); return mp_const_none; diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h index 13f75b2c9..94c43f81e 100644 --- a/shared-module/bleio/Characteristic.h +++ b/shared-module/bleio/Characteristic.h @@ -33,7 +33,6 @@ typedef struct { mp_obj_base_t base; bleio_service_obj_t *service; - uint16_t service_handle; // TODO: Is this needed? bleio_uuid_obj_t *uuid; mp_obj_t value_data; uint16_t handle; -- cgit v1.2.3 From 19fab4af5ad1261ea91bc1aacbed35f40a9bff3a Mon Sep 17 00:00:00 2001 From: arturo182 Date: Mon, 23 Jul 2018 23:55:15 +0200 Subject: bleio: Remove deep copy constructor for UUID --- ports/nrf/common-hal/bleio/UUID.c | 11 ----------- shared-bindings/bleio/UUID.c | 1 - 2 files changed, 12 deletions(-) diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index 4d4c8c9fb..891c34ac4 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -105,17 +105,6 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uui return; } - // deep copy - if (MP_OBJ_IS_TYPE(*uuid, &bleio_uuid_type)) { - bleio_uuid_obj_t *other = MP_OBJ_TO_PTR(*uuid); - self->type = other->type; - self->uuid_vs_idx = other->uuid_vs_idx; - self->value[0] = other->value[0]; - self->value[1] = other->value[1]; - - return; - } - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid UUID parameter")); } diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 93a2051c1..54ed582d5 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -87,7 +87,6 @@ enum { //| //| - a `int` value in range of 0 to 0xFFFF //| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit -//| - another UUID object //| //| :param int/str uuid: The uuid to encapsulate //| -- cgit v1.2.3 From 684f2673ce558f90607f7fc3d294561e6803edbe Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 25 Jul 2018 23:15:02 +0200 Subject: bleio: Remove unneeded TODO --- shared-bindings/bleio/AdvertisementData.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c index 545dd5c51..9cfdd74e9 100644 --- a/shared-bindings/bleio/AdvertisementData.c +++ b/shared-bindings/bleio/AdvertisementData.c @@ -35,8 +35,6 @@ //| Represents the data to be broadcast during BLE advertising. //| -// TODO: Implement constructor and methods - STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = { // Static variables { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) }, -- cgit v1.2.3 From beee58a56f8105efa5c4d1b4450636fd14ef4bc3 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 25 Jul 2018 23:15:23 +0200 Subject: bleio: Add scan_entry as an param for the Device constructor --- shared-bindings/bleio/Device.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index ec7121f54..756a5e05d 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -41,6 +41,7 @@ #include "shared-bindings/bleio/UUID.h" #include "shared-module/bleio/AdvertisementData.h" #include "shared-module/bleio/Device.h" +#include "shared-module/bleio/ScanEntry.h" //| .. currentmodule:: bleio //| @@ -87,12 +88,13 @@ //| central.connect() //| -//| .. class:: Device(address=None) +//| .. class:: Device(address=None, scan_entry=None) //| -//| Create a new Device object. If the `address` parameter is not `None`, +//| Create a new Device object. If the `address` or `scan_entry` parameters are not `None`, //| the role is set to Central, otherwise it's set to Peripheral. //| //| :param bleio.Address address: The address of the device to connect to +//| :param bleio.ScanEntry scan_entry: The scan entry returned from `bleio.Scanner` //| //| .. attribute:: name @@ -167,16 +169,17 @@ STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - //TODO: Add ScanEntry - enum { ARG_address }; + enum { ARG_address, ARG_scan_entry }; static const mp_arg_t allowed_args[] = { { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; 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); const mp_obj_t address_obj = args[ARG_address].u_obj; + const mp_obj_t scan_entry_obj = args[ARG_scan_entry].u_obj; if (address_obj != mp_const_none) { bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj); @@ -184,6 +187,12 @@ STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, self->is_peripheral = false; self->address.type = address->type; memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES); + } else if (scan_entry_obj != mp_const_none) { + bleio_scanentry_obj_t *scan_entry = MP_OBJ_TO_PTR(scan_entry_obj); + + self->is_peripheral = false; + self->address.type = scan_entry->address.type; + memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES); } else { self->name = mp_obj_new_str(default_name, strlen(default_name), false); common_hal_bleio_adapter_get_address(&self->address); -- cgit v1.2.3 From ad466b3edbf5848febf062dff125e6a019ac88f5 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Wed, 25 Jul 2018 23:20:40 +0200 Subject: bleio: Let Characteristic inherit the Services UUID length --- shared-bindings/bleio/Service.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 94d245d7f..a5043a346 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -113,7 +113,10 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); - // TODO: If service is 128b then update Chara UUID to be 128b too + if (self->uuid->type == UUID_TYPE_128BIT) { + characteristic->uuid->type = UUID_TYPE_128BIT; + characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx; + } common_hal_bleio_service_add_characteristic(self, characteristic); -- cgit v1.2.3 From eceb21a0175bd6109c81c7fa0def81dd57fdfe9c Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 26 Jul 2018 00:04:48 +0200 Subject: bleio: Don't register the services until needed Because of the very specific way nRF requires service registration (characteristics can be added only to last added service), we would have to write the Python code in a specific way. With this patch the user has more freedom. --- ports/nrf/common-hal/bleio/Device.c | 30 ++++++++++++++++++++++++++++++ ports/nrf/common-hal/bleio/Service.c | 24 ------------------------ shared-bindings/bleio/Device.c | 8 ++++++++ shared-bindings/bleio/Device.h | 2 ++ shared-bindings/bleio/Service.c | 5 +---- shared-bindings/bleio/Service.h | 1 - 6 files changed, 41 insertions(+), 29 deletions(-) diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index fd772c04d..c03db0ab9 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -490,6 +490,36 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { } } +void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) { + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) + }; + + if (service->uuid->type == UUID_TYPE_128BIT) { + uuid.type = service->uuid->uuid_vs_idx; + } + + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (service->is_secondary) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } + + common_hal_bleio_adapter_set_enabled(true); + + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Failed to add service, status: 0x%08lX", err_code)); + } + + const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); + for (size_t i = 0; i < char_list->len; ++i) { + bleio_characteristic_obj_t *characteristic = char_list->items[i]; + common_hal_bleio_service_add_characteristic(service, characteristic); + } +} + void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) { if (connectable) { ble_drv_add_event_handler(on_ble_evt, device); diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index 93588d156..ee2624073 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -30,30 +30,6 @@ #include "shared-bindings/bleio/Service.h" #include "shared-bindings/bleio/Adapter.h" -void common_hal_bleio_service_construct(bleio_service_obj_t *self) { - ble_uuid_t uuid = { - .type = BLE_UUID_TYPE_BLE, - .uuid = self->uuid->value[0] | (self->uuid->value[1] << 8) - }; - - if (self->uuid->type == UUID_TYPE_128BIT) { - uuid.type = self->uuid->uuid_vs_idx; - } - - uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; - if (self->is_secondary) { - service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; - } - - common_hal_bleio_adapter_set_enabled(true); - - const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &self->handle); - if (err_code != NRF_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to add service, status: 0x%08lX", err_code)); - } -} - void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { ble_gatts_char_md_t char_md = { .char_props.broadcast = characteristic->props.broadcast, diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 756a5e05d..e89bc45a2 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -291,6 +291,14 @@ STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); } + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + for (size_t i = 0; i < service_list->len; ++i) { + bleio_service_obj_t *service = service_list->items[i]; + if (service->handle == 0xFFFF) { + common_hal_bleio_device_add_service(self, service); + } + } + common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); return mp_const_none; diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Device.h index f989736dd..aebf1d639 100644 --- a/shared-bindings/bleio/Device.h +++ b/shared-bindings/bleio/Device.h @@ -29,9 +29,11 @@ #include "shared-module/bleio/AdvertisementData.h" #include "shared-module/bleio/Device.h" +#include "shared-module/bleio/Service.h" extern const mp_obj_type_t bleio_device_type; +extern void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service); extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device); extern void common_hal_bleio_device_connect(bleio_device_obj_t *device); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index a5043a346..6e112880a 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -76,6 +76,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, self->base.type = &bleio_service_type; self->device = NULL; self->char_list = mp_obj_new_list(0, NULL); + self->handle = 0xFFFF; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); @@ -104,8 +105,6 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, "Invalid UUID parameter")); } - common_hal_bleio_service_construct(self); - return MP_OBJ_FROM_PTR(self); } @@ -118,8 +117,6 @@ STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t char characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx; } - common_hal_bleio_service_add_characteristic(self, characteristic); - characteristic->service = self; mp_obj_list_append(self->char_list, characteristic); diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h index 6e3079cf9..77c751829 100644 --- a/shared-bindings/bleio/Service.h +++ b/shared-bindings/bleio/Service.h @@ -32,7 +32,6 @@ const mp_obj_type_t bleio_service_type; -extern void common_hal_bleio_service_construct(bleio_service_obj_t *self); extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H -- cgit v1.2.3 From 13dd27a04760867a7ccb6d59fd339536ce588e25 Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 26 Jul 2018 00:07:14 +0200 Subject: bleio: Remove UUID static variables --- shared-bindings/bleio/UUID.c | 84 -------------------------------------------- 1 file changed, 84 deletions(-) diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 54ed582d5..26e3a84c8 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -29,48 +29,6 @@ #include "py/runtime.h" #include "shared-bindings/bleio/UUID.h" -enum { - ServiceUuidGenericAccess = 0x1800, - ServiceUuidGenericAttribute = 0x1801, - ServiceUuidImmediateAlert = 0x1802, - ServiceUuidLinkLoss = 0x1803, - ServiceUuidTxPower = 0x1804, - ServiceUuidCurrentTimeServiceService = 0x1805, - ServiceUuidReferenceTimeUpdateService = 0x1806, - ServiceUuidNextDSTChangeService = 0x1807, - ServiceUuidGlucose = 0x1808, - ServiceUuidHealthThermometer = 0x1809, - ServiceUuidDeviceInformation = 0x180A, - ServiceUuidHeartRate = 0x180D, - ServiceUuidPhoneAlertStatusService = 0x180E, - ServiceUuidBatteryService = 0x180F, - ServiceUuidBloodPressure = 0x1810, - ServiceUuidAlertNotificationService = 0x1811, - ServiceUuidHumanInterfaceDevice = 0x1812, - ServiceUuidScanParameters = 0x1813, - ServiceUuidRunningSpeedAndCadence = 0x1814, - ServiceUuidAutomationIO = 0x1815, - ServiceUuidCyclingSpeedAndCadence = 0x1816, - ServiceUuidCyclingPower = 0x1818, - ServiceUuidLocationAndNavigation = 0x1819, - ServiceUuidEnvironmentalSensing = 0x181A, - ServiceUuidBodyComposition = 0x181B, - ServiceUuidUserData = 0x181C, - ServiceUuidWeightScale = 0x181D, - ServiceUuidBondManagementService = 0x181E, - ServiceUuidContinuousGlucoseMonitoring = 0x181F, - ServiceUuidInternetProtocolSupportService = 0x1820, - ServiceUuidIndoorPositioning = 0x1821, - ServiceUuidPulseOximeterService = 0x1822, - ServiceUuidHTTPProxy = 0x1823, - ServiceUuidTransportDiscovery = 0x1824, - ServiceUuidObjectTransferService = 0x1825, - ServiceUuidFitnessMachine = 0x1826, - ServiceUuidMeshProvisioningService = 0x1827, - ServiceUuidMeshProxyService = 0x1828, - ServiceUuidReconnectionConfiguration = 0x1829, -}; - //| .. currentmodule:: bleio //| //| :class:`UUID` -- BLE UUID @@ -151,49 +109,7 @@ const mp_obj_property_t bleio_uuid_type_obj = { }; STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { - // Properties { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_uuid_type_obj) }, - - // Static variables - { MP_ROM_QSTR(MP_QSTR_SERVICE_GENERIC_ACCESS), MP_ROM_INT(ServiceUuidGenericAccess) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_GENERIC_ATTRIBUTE), MP_ROM_INT(ServiceUuidGenericAttribute) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_IMMEDIATE_ALERT), MP_ROM_INT(ServiceUuidImmediateAlert) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_LINK_LOSS), MP_ROM_INT(ServiceUuidLinkLoss) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_TX_POWER), MP_ROM_INT(ServiceUuidTxPower) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_CURRENT_TIME_SERVICE), MP_ROM_INT(ServiceUuidCurrentTimeServiceService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_REFERENCE_TIME_UPDATE_SERVICE), MP_ROM_INT(ServiceUuidReferenceTimeUpdateService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_NEXT_DST_CHANGE_SERVICE), MP_ROM_INT(ServiceUuidNextDSTChangeService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_GLUCOSE), MP_ROM_INT(ServiceUuidGlucose) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_HEALTH_THERMOMETER), MP_ROM_INT(ServiceUuidHealthThermometer) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_DEVICE_INFORMATION), MP_ROM_INT(ServiceUuidDeviceInformation) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_HEART_RATE), MP_ROM_INT(ServiceUuidHeartRate) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_PHONE_ALERT_STATUS_SERVICE), MP_ROM_INT(ServiceUuidPhoneAlertStatusService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_BATTERY_SERVICE), MP_ROM_INT(ServiceUuidBatteryService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_BLOOD_PRESSURE), MP_ROM_INT(ServiceUuidBloodPressure) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_ALERT_NOTIFICATION_SERVICE), MP_ROM_INT(ServiceUuidAlertNotificationService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_HUMAN_INTERFACE_DEVICE), MP_ROM_INT(ServiceUuidHumanInterfaceDevice) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_SCAN_PARAMETERS), MP_ROM_INT(ServiceUuidScanParameters) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_RUNNING_SPEED_AND_CADENCE), MP_ROM_INT(ServiceUuidRunningSpeedAndCadence) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_AUTOMATION_IO), MP_ROM_INT(ServiceUuidAutomationIO) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_CYCLING_SPEED_AND_CADENCE), MP_ROM_INT(ServiceUuidCyclingSpeedAndCadence) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_CYCLING_POWER), MP_ROM_INT(ServiceUuidCyclingPower) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_LOCATION_AND_NAVIGATION), MP_ROM_INT(ServiceUuidLocationAndNavigation) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_ENVIRONMENTAL_SENSING), MP_ROM_INT(ServiceUuidEnvironmentalSensing) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_BODY_COMPOSITION), MP_ROM_INT(ServiceUuidBodyComposition) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_USER_DATA), MP_ROM_INT(ServiceUuidUserData) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_WEIGHT_SCALE), MP_ROM_INT(ServiceUuidWeightScale) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_BOND_MANAGEMENT_SERVICE), MP_ROM_INT(ServiceUuidBondManagementService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_CONTINUOUS_GLUCOSE_MONITORING), MP_ROM_INT(ServiceUuidContinuousGlucoseMonitoring) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_INTERNET_PROTOCOL_SUPPORT_SERVICE), MP_ROM_INT(ServiceUuidInternetProtocolSupportService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_INDOOR_POSITIONING), MP_ROM_INT(ServiceUuidIndoorPositioning) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_PULSE_OXIMETER_SERVICE), MP_ROM_INT(ServiceUuidPulseOximeterService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_HTTP_PROXY), MP_ROM_INT(ServiceUuidHTTPProxy) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_TRANSPORT_DISCOVERY), MP_ROM_INT(ServiceUuidTransportDiscovery) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_OBJECT_TRANSFER_SERVICE), MP_ROM_INT(ServiceUuidObjectTransferService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_FITNESS_MACHINE), MP_ROM_INT(ServiceUuidFitnessMachine) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_MESH_PROVISIONING_SERVICE), MP_ROM_INT(ServiceUuidMeshProvisioningService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_MESH_PROXY_SERVICE), MP_ROM_INT(ServiceUuidMeshProxyService) }, - { MP_ROM_QSTR(MP_QSTR_SERVICE_RECONNECTION_CONFIGURATION), MP_ROM_INT(ServiceUuidReconnectionConfiguration) } }; STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); -- cgit v1.2.3 From 5354aeab4c2aaee53c07caa6242701cbac069d2d Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 26 Jul 2018 00:14:23 +0200 Subject: bleio: Allow using len() on UUID --- shared-bindings/bleio/UUID.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index 26e3a84c8..7cef9a26f 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -49,6 +49,16 @@ //| :param int/str uuid: The uuid to encapsulate //| +//| .. method:: __len__() +//| +//| Returns the uuid length in bits +//| +//| This allows you to: +//| +//| uuid = bleio.UUID(0x1801) +//| print(len(uuid)) +//| + //| .. attribute:: type //| //| The UUID type. One of: @@ -79,6 +89,18 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si return MP_OBJ_FROM_PTR(self); } +STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); + const uint8_t len = (type == UUID_TYPE_16BIT) ? 16 : 128; + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -119,5 +141,6 @@ const mp_obj_type_t bleio_uuid_type = { .name = MP_QSTR_UUID, .print = bleio_uuid_print, .make_new = bleio_uuid_make_new, + .unary_op = bleio_uuid_unary_op, .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict }; -- cgit v1.2.3 From c62b708012378f53ccb8c2691f79203e1d698f4b Mon Sep 17 00:00:00 2001 From: arturo182 Date: Thu, 26 Jul 2018 00:16:36 +0200 Subject: bleio: Fix docs error --- shared-bindings/bleio/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index e89bc45a2..64cfb762f 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -90,7 +90,7 @@ //| .. class:: Device(address=None, scan_entry=None) //| -//| Create a new Device object. If the `address` or `scan_entry` parameters are not `None`, +//| Create a new Device object. If the `address` or :py:data:`scan_entry` parameters are not `None`, //| the role is set to Central, otherwise it's set to Peripheral. //| //| :param bleio.Address address: The address of the device to connect to -- cgit v1.2.3 From 4bc24c4f6084e414f0fb00299aae7d7cfdb76aba Mon Sep 17 00:00:00 2001 From: arturo182 Date: Fri, 31 Aug 2018 21:34:01 +0200 Subject: bleio: Fix errors after rebase --- .travis.yml | 2 +- conf.py | 2 +- locale/circuitpython.pot | 233 ++++++++++++-------- locale/de_DE.po | 253 +++++++++++++--------- locale/en_US.po | 233 ++++++++++++-------- locale/es.po | 324 +++++++++++++++++----------- locale/fil.po | 321 ++++++++++++++++----------- locale/fr.po | 320 ++++++++++++++++----------- locale/it_IT.po | 321 ++++++++++++++++----------- locale/pt_BR.po | 317 ++++++++++++++++----------- ports/nrf/Makefile | 7 +- ports/nrf/common-hal/bleio/Adapter.c | 8 +- ports/nrf/common-hal/bleio/Characteristic.c | 12 +- ports/nrf/common-hal/bleio/Device.c | 32 +-- ports/nrf/common-hal/bleio/Scanner.c | 4 +- ports/nrf/common-hal/bleio/Service.c | 2 +- ports/nrf/common-hal/bleio/UUID.c | 6 +- shared-bindings/bleio/Address.c | 4 +- shared-bindings/bleio/Characteristic.c | 2 +- shared-bindings/bleio/Device.c | 12 +- shared-bindings/bleio/ScanEntry.c | 2 +- shared-bindings/bleio/Service.c | 2 +- 22 files changed, 1472 insertions(+), 947 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6cfa869b0..821165cce 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ before_script: - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) # For nrf builds - - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh) + - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/bluetooth/download_ble_stack.sh) # For huzzah builds - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar -C .. -xavf xtensa-lx106-elf-standalone.tar.gz)) diff --git a/conf.py b/conf.py index 0f363923f..d4b7c7234 100644 --- a/conf.py +++ b/conf.py @@ -114,7 +114,7 @@ exclude_patterns = ["**/build*", "ports/esp8266/modules", "ports/minimal", "ports/nrf/device", - "ports/nrf/drivers", + "ports/nrf/bluetooth", "ports/nrf/modules", "ports/nrf/nrfx", "ports/nrf/peripherals", diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 83662734a..9f2e29430 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -291,12 +291,12 @@ msgid "Too many channels in sample." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -312,43 +312,44 @@ msgstr "" msgid "sampling rate out of range" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -361,7 +362,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "" @@ -413,8 +414,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "" @@ -695,143 +696,165 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:95 -msgid "All I2C peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 -msgid "All SPI peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format -msgid "error = 0x%08lX" +msgid "Failed to get softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:86 -msgid "Invalid buffer size" +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:90 -msgid "Odd parity is not supported" +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#: ports/nrf/common-hal/bleio/Characteristic.c:91 #, c-format -msgid "Can not get temperature. status: 0x%02x" +msgid "Failed to read attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 -msgid "All PWM peripherals are in use" +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#: ports/nrf/common-hal/bleio/Device.c:592 #, c-format -msgid "Can not apply advertisement data. status: 0x%02x" +msgid "Failed to create mutex, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#: ports/nrf/common-hal/bleio/Service.c:83 #, c-format -msgid "Can not start advertisement. status: 0x%02x" +msgid "Failed to add characteristic, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#: ports/nrf/common-hal/bleio/UUID.c:97 #, c-format -msgid "Can not stop advertisement. status: 0x%02x" +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" +#: ports/nrf/common-hal/busio/SPI.c:115 +msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#: ports/nrf/common-hal/busio/UART.c:48 #, c-format -msgid "Can not connect. status: 0x%02x" +msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" msgstr "" #: ports/unix/modffi.c:138 @@ -1994,7 +2017,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "" @@ -2087,6 +2110,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2201,7 +2248,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "" @@ -2263,7 +2310,7 @@ msgstr "" msgid "Read-only" msgstr "" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index de9a21e96..4f62ba4f9 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -300,12 +300,12 @@ msgid "Too many channels in sample." msgstr "Zu viele Kanäle im sample" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "Kein DMA Kanal gefunden" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren" @@ -321,43 +321,44 @@ msgstr "Nur 8 oder 16 bit mono mit " msgid "sampling rate out of range" msgstr "Abtastrate außerhalb der Reichweite" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "DAC wird schon benutzt" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "Rechter Kanal wird nicht unterstützt" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "Ungültiger Pin" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Ungültiger Pin für linken Kanal" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Ungültiger Pin für rechten Kanal" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "Kann nicht beite Kanäle auf dem gleichen Pin ausgeben" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Alle timer werden benutzt" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Alle event Kanälre werden benutzt" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -370,7 +371,7 @@ msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "Ungültige Pins" @@ -422,8 +423,8 @@ msgstr "Reset zum bootloader nicht möglich da bootloader nicht vorhanden" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Ungültige PWM Frequenz" @@ -704,150 +705,172 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:95 -#, fuzzy -msgid "All I2C peripherals are in use" -msgstr "Alle timer werden benutzt" - -#: ports/nrf/common-hal/busio/SPI.c:115 -#, fuzzy -msgid "All SPI peripherals are in use" -msgstr "Alle timer werden benutzt" - -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/bleio/Adapter.c:41 #, c-format -msgid "error = 0x%08lX" +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:86 -#, fuzzy -msgid "Invalid buffer size" -msgstr "ungültiger dupterm index" - -#: ports/nrf/common-hal/busio/UART.c:90 -#, fuzzy -msgid "Odd parity is not supported" -msgstr "bytes mit merh als 8 bits werden nicht unterstützt" - -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format -msgid "Can not get temperature. status: 0x%02x" +msgid "Failed to get softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 -#, fuzzy -msgid "All PWM peripherals are in use" -msgstr "Alle timer werden benutzt" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, c-format +msgid "Failed to read attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#: ports/nrf/common-hal/bleio/Device.c:436 #, c-format -msgid "Can not apply advertisement data. status: 0x%02x" +msgid "Failed to connect, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#: ports/nrf/common-hal/bleio/Device.c:513 #, c-format -msgid "Can not start advertisement. status: 0x%02x" +msgid "Failed to add service, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#: ports/nrf/common-hal/bleio/Device.c:531 #, c-format -msgid "Can not stop advertisement. status: 0x%02x" +msgid "Failed to start advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 +#: ports/nrf/common-hal/bleio/Device.c:549 #, c-format -msgid "Can not read attribute value. status: 0x%02x" +msgid "Failed to stop advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 #, c-format -msgid "Can not write attribute value. status: 0x%02x" +msgid "Failed to start scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 +#: ports/nrf/common-hal/bleio/Device.c:592 #, c-format -msgid "Can not notify attribute value. status: 0x%02x" +msgid "Failed to create mutex, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 +#: ports/nrf/common-hal/bleio/Service.c:83 #, c-format -msgid "Can not start scanning. status: 0x%02x" +msgid "Failed to add characteristic, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#: ports/nrf/common-hal/bleio/UUID.c:97 #, c-format -msgid "Can not connect. status: 0x%02x" +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" +#: ports/nrf/common-hal/busio/I2C.c:96 +#, fuzzy +msgid "All I2C peripherals are in use" +msgstr "Alle timer werden benutzt" + +#: ports/nrf/common-hal/busio/SPI.c:115 +#, fuzzy +msgid "All SPI peripherals are in use" +msgstr "Alle timer werden benutzt" + +#: ports/nrf/common-hal/busio/UART.c:48 +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c:86 +#, fuzzy +msgid "Invalid buffer size" +msgstr "ungültiger dupterm index" + +#: ports/nrf/common-hal/busio/UART.c:90 +#, fuzzy +msgid "Odd parity is not supported" +msgstr "bytes mit merh als 8 bits werden nicht unterstützt" + +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" msgstr "" +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +#, fuzzy +msgid "All PWM peripherals are in use" +msgstr "Alle timer werden benutzt" + #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "" @@ -2009,7 +2032,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "" @@ -2105,6 +2128,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2220,7 +2267,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "" @@ -2282,7 +2329,7 @@ msgstr "" msgid "Read-only" msgstr "" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index 15c97e329..1963390e2 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -291,12 +291,12 @@ msgid "Too many channels in sample." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -312,43 +312,44 @@ msgstr "" msgid "sampling rate out of range" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -361,7 +362,7 @@ msgstr "" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "" @@ -413,8 +414,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "" @@ -695,143 +696,165 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:95 -msgid "All I2C peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 -msgid "All SPI peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format -msgid "error = 0x%08lX" +msgid "Failed to get softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:86 -msgid "Invalid buffer size" +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:90 -msgid "Odd parity is not supported" +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#: ports/nrf/common-hal/bleio/Characteristic.c:91 #, c-format -msgid "Can not get temperature. status: 0x%02x" +msgid "Failed to read attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 -msgid "All PWM peripherals are in use" +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#: ports/nrf/common-hal/bleio/Device.c:592 #, c-format -msgid "Can not apply advertisement data. status: 0x%02x" +msgid "Failed to create mutex, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#: ports/nrf/common-hal/bleio/Service.c:83 #, c-format -msgid "Can not start advertisement. status: 0x%02x" +msgid "Failed to add characteristic, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#: ports/nrf/common-hal/bleio/UUID.c:97 #, c-format -msgid "Can not stop advertisement. status: 0x%02x" +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" +#: ports/nrf/common-hal/busio/SPI.c:115 +msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#: ports/nrf/common-hal/busio/UART.c:48 #, c-format -msgid "Can not connect. status: 0x%02x" +msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" msgstr "" #: ports/unix/modffi.c:138 @@ -1994,7 +2017,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "" @@ -2087,6 +2110,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2201,7 +2248,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "" @@ -2263,7 +2310,7 @@ msgstr "" msgid "Read-only" msgstr "" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "" diff --git a/locale/es.po b/locale/es.po index 60452ae34..71e2089f5 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -306,12 +306,12 @@ msgid "Too many channels in sample." msgstr "Demasiados canales en sample" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "No se encontró el canal DMA" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "No se pudieron asignar buffers para la conversión con signo" @@ -327,43 +327,44 @@ msgstr "Solo mono de 8 o 16 bit con" msgid "sampling rate out of range" msgstr "velocidad de muestreo fuera de rango" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "DAC ya está siendo utilizado" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "El canal derecho no tiene soporte" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "pin inválido" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Pin inválido para canal izquierdo" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Pin inválido para canal derecho" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "No es posible utilizar el mismo pin para ambos canales" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Todos los timers están siendo utilizados" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Todos los canales de eventos están siendo utilizados" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor que %d" @@ -376,7 +377,7 @@ msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "pines inválidos" @@ -428,8 +429,8 @@ msgstr "No se puede reiniciar en bootloader porque no hay bootloader presente." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Frecuencia PWM inválida" @@ -712,7 +713,131 @@ msgstr "parámetro config desconocido" msgid "AnalogOut functionality not supported" msgstr "Funcionalidad AnalogOut no soportada" -#: ports/nrf/common-hal/busio/I2C.c:95 +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Los datos no caben en el paquete de anuncio." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "No se puede conectar. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "No se puede inicar el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "No se puede agregar el UUID de 128-bits Especifico del Vendedor." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Longitud de string UUID inválida" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parámetro UUID inválido" + +#: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo utilizados" @@ -746,112 +871,11 @@ msgstr "busio.UART no disponible" msgid "Can not get temperature. status: 0x%02x" msgstr "No se puede obtener la temperatura. status: 0x%02x" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" msgstr "Todos los timers están siendo utilizados" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "No se pueden aplicar los parámetros GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "No se pueden establecer los parámetros PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "No se puede consultar la dirección del dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "No se puede agregar el UUID de 128-bits Especifico del Vendedor." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "No se puede agregar el Servicio" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "No se puede agregar la Característica" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "No se puede aplicar el nombre del dispositivo en el stack." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "No se puede codificar el UUID, para revisar la longitud." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Se puede codificar el UUID en el paquete de anuncio." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Los datos no caben en el paquete de anuncio." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "No se puede inicar el anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "No se puede detener el anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "No se puede leer el valor del atributo. status 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "No se puede escribir el valor del atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "No se puede iniciar el escaneo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "No se puede conectar. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parámetro UUID inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo de Servicio inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Longitud de string UUID inválida" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "" @@ -2036,7 +2060,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "" @@ -2094,8 +2118,8 @@ msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -"sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' o" -"'B'" +"sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' " +"o'B'" #: shared-bindings/audioio/RawSample.c:104 msgid "buffer must be a bytes-like object" @@ -2131,6 +2155,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2246,7 +2294,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "" @@ -2309,7 +2357,7 @@ msgstr "" msgid "Read-only" msgstr "Solo lectura" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "" @@ -2501,3 +2549,33 @@ msgstr "" #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Baud rate demasiado alto para este periférico SPI" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." + +#~ msgid "Can not add Characteristic." +#~ msgstr "No se puede agregar la Característica" + +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio" + +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." diff --git a/locale/fil.po b/locale/fil.po index e4f3105c9..f6df8fa20 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -303,12 +303,12 @@ msgid "Too many channels in sample." msgstr "Sobra ang channels sa sample." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "Walang DMA channel na mahanap" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "Hindi ma-allocate ang buffers para sa naka-sign na conversion" @@ -324,43 +324,44 @@ msgstr "Tanging 8 o 16 na bit mono na may " msgid "sampling rate out of range" msgstr "pagpili ng rate wala sa sakop" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "Ginagamit na ang DAC" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "Hindi supportado ang kanang channel" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "Mali ang pin" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Mali ang pin para sa kaliwang channel" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Mali ang pin para sa kanang channel" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "Hindi maaaring output ang mga parehong channel sa parehong pin" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Lahat ng timer ginagamit" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Lahat ng event channels ginagamit" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -373,7 +374,7 @@ msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "Mali ang pins" @@ -425,8 +426,8 @@ msgstr "Hindi ma-reset sa bootloader dahil walang bootloader." #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Mali ang PWM frequency" @@ -710,7 +711,131 @@ msgstr "hindi alam na config param" msgid "AnalogOut functionality not supported" msgstr "Hindi supportado ang AnalogOut" -#: ports/nrf/common-hal/busio/I2C.c:95 +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Hindi maisulat ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Hindi mabalitaan ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Hindi maisulat ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Hindi makasya ang data sa loob ng advertisement packet." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Hindi makaconnect. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Hindi mahinto ang advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Hindi masimulaan ang advertisement. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Hindi mahinto ang advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Hindi maaaring magdagdag ng Vendor Specific na 128-bit UUID." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Mali ang UUID string length" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Mali ang UUID parameter" + +#: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Lahat ng timer ginagamit" @@ -748,112 +873,11 @@ msgstr "" msgid "Can not get temperature. status: 0x%02x" msgstr "Hindi makuha ang temperatura. status 0x%02x" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Hindi ma-apply ang GAP parameters." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Hindi ma-set ang PPCP parameters." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Hindi maaaring mag-query para sa address ng device." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Hindi maaaring magdagdag ng Vendor Specific na 128-bit UUID." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Hindi maidaragdag ang serbisyo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Hindi mabasa and Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Hindi maaaring ma-aplay ang device name sa stack." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Hindi ma-encode UUID, para suriin ang haba." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Maaring i-encode ang UUID sa advertisement packet." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Hindi makasya ang data sa loob ng advertisement packet." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Hindi masimulaan ang advertisement. status 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Hindi mahinto ang advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Hindi maisulat ang attribute value. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Hindi mabalitaan ang attribute value. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Hindi makaconnect. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Mali ang UUID parameter" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Mali ang tipo ng serbisyo" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Mali ang UUID string length" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Hindi alam ang type" @@ -2033,7 +2057,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "AnalogOut ay 16 bits. Value ay dapat hindi hihigit pa sa 65536." #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "Hindi playing" @@ -2137,6 +2161,31 @@ msgstr "Mali ang bilang ng bits" msgid "buffer slices must be of equal length" msgstr "aarehas na haba dapat ang buffer slices" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "mali ang bilang ng argumento" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "Kailangan ng lock ang function." @@ -2265,7 +2314,7 @@ msgstr "walang laman ang address" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "Umasa ng %q" @@ -2329,7 +2378,7 @@ msgstr "index ay dapat int" msgid "Read-only" msgstr "Basahin-lamang" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "May halfwords (type 'H') dapat ang array" @@ -2524,3 +2573,33 @@ msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "ang palette ay dapat 32 bytes ang haba" + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Hindi mabasa and Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." + +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." diff --git a/locale/fr.po b/locale/fr.po index 02beae6d0..8949a6899 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -298,12 +298,12 @@ msgid "Too many channels in sample." msgstr "Trop de canaux dans l'échantillon." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "Aucun canal DMA trouvé" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "Impossible d'allouer des tampons pour une conversion signée" @@ -319,43 +319,44 @@ msgstr "Uniquement 8 ou 16 bit mono avec " msgid "sampling rate out of range" msgstr "taux d'échantillonage hors gamme" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "DAC déjà utilisé" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "Canal droit non supporté" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "Broche invalide" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Broche invalide pour le canal gauche" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Broche invalide pour le canal droit" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "On ne peut mettre les deux canaux sur la même broche" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Tous les timers sont utilisés" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Tous les canaux d'événements sont utilisés" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -368,7 +369,7 @@ msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "Broche invalide" @@ -421,8 +422,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Fréquence de PWM invalide" @@ -706,7 +707,130 @@ msgstr "paramètre de config. inconnu" msgid "AnalogOut functionality not supported" msgstr "AnalogOut non supporté" -#: ports/nrf/common-hal/busio/I2C.c:95 +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Connection impossible. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Longeur de chaîne UUID invalide" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Paramètre UUID invalide" + +#: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" msgstr "Tous les timers sont utilisés" @@ -745,112 +869,11 @@ msgstr "busio.UART n'est pas disponible" msgid "Can not get temperature. status: 0x%02x" msgstr "Impossible de lire la température. status: 0x%02x" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Impossible d'appliquer les paramètres GAP" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Impossible d'appliquer les paramètres PPCP" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Impossible d'obtenir l'adresse du périphérique" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Impossible d'ajouter le Service" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Impossible d'ajouter la Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Impossible d'appliquer le nom de périphérique dans la pile" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Impossible de commencer à scanner. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Connection impossible. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Paramètre UUID invalide" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Type de service invalide" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Longeur de chaîne UUID invalide" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Type inconnu" @@ -2027,7 +2050,7 @@ msgstr "" "65536." #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "En pause" @@ -2128,6 +2151,31 @@ msgstr "Nombre de bits invalide" msgid "buffer slices must be of equal length" msgstr "les slices de tampon doivent être de longueurs égales" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "mauvais nombres d'arguments" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "La fonction nécessite un verrou." @@ -2258,7 +2306,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "Attendu : %q" @@ -2325,7 +2373,7 @@ msgstr "l'index doit être un entier" msgid "Read-only" msgstr "Lecture seule" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "Le tableau doit contenir des halfwords (type 'H')" @@ -2517,10 +2565,34 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" + #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" diff --git a/locale/it_IT.po b/locale/it_IT.po index 5490c699c..b3346e956 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -305,12 +305,12 @@ msgid "Too many channels in sample." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "Nessun canale DMA trovato" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "Ipossibilitato ad allocare buffer per la conversione con segno" @@ -326,43 +326,44 @@ msgstr "" msgid "sampling rate out of range" msgstr "frequenza di campionamento fuori intervallo" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "DAC già in uso" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "Canale destro non supportato" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "Pin non valido" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Pin non valido per il canale sinistro" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Pin non valido per il canale destro" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "Impossibile dare in output entrambi i canal sullo stesso pin" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Tutti i timer utilizzati" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Tutti i canali eventi utilizati" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "" @@ -376,7 +377,7 @@ msgstr "Non sono presenti abbastanza pin" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "Pin non validi" @@ -429,8 +430,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Frequenza PWM non valida" @@ -712,7 +713,131 @@ msgstr "parametro di configurazione sconosciuto" msgid "AnalogOut functionality not supported" msgstr "funzionalità AnalogOut non supportata" -#: ports/nrf/common-hal/busio/I2C.c:95 +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Impossibile connettersi. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Lunghezza della stringa UUID non valida" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parametro UUID non valido" + +#: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -749,112 +874,11 @@ msgstr "busio.UART non ancora implementato" msgid "Can not get temperature. status: 0x%02x" msgstr "Impossibile leggere la temperatura. status: 0x%02x" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" msgstr "Tutte le periferiche SPI sono in uso" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Impossibile applicare i parametri GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Impossibile impostare i parametri PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Non è possibile aggiungere Service." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Non è possibile aggiungere Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Non è possibile inserire il nome del dipositivo nella lista." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Impossibile inserire dati nel pacchetto di advertisement." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Impossible inserire dati advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Impossibile avviare advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Impossibile fermare advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Impossible iniziare la scansione. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Impossibile connettersi. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parametro UUID non valido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo di servizio non valido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Lunghezza della stringa UUID non valida" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Tipo sconosciuto" @@ -2029,7 +2053,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "AnalogOut ha solo 16 bit. Il valore deve essere meno di 65536." #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "In pausa" @@ -2132,6 +2156,31 @@ msgstr "Numero di bit non valido" msgid "buffer slices must be of equal length" msgstr "slice del buffer devono essere della stessa lunghezza" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "numero di argomenti errato" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2248,7 +2297,7 @@ msgstr "gli indirizzi sono vuoti" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "Atteso un %q" @@ -2315,7 +2364,7 @@ msgstr "l'indice deve essere int" msgid "Read-only" msgstr "Sola lettura" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "" @@ -2504,3 +2553,33 @@ msgstr "'S' e 'O' non sono formati supportati" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "troppi argomenti forniti con il formato specificato" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index f3d055c08..25c645106 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-09 20:51-0400\n" +"POT-Creation-Date: 2018-10-21 17:15+0200\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -291,12 +291,12 @@ msgid "Too many channels in sample." msgstr "Muitos canais na amostra." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:305 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:339 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:417 msgid "No DMA channel found" msgstr "Nenhum canal DMA encontrado" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:308 -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:341 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:419 msgid "Unable to allocate buffers for signed conversion" msgstr "Não é possível alocar buffers para conversão assinada" @@ -312,43 +312,44 @@ msgstr "" msgid "sampling rate out of range" msgstr "Taxa de amostragem fora do intervalo" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:69 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:132 msgid "DAC already in use" msgstr "DAC em uso" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:73 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:136 msgid "Right channel unsupported" msgstr "Canal direito não suportado" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:76 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:139 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:116 #: ports/atmel-samd/common-hal/touchio/TouchIn.c:65 msgid "Invalid pin" msgstr "Pino inválido" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:84 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:147 msgid "Invalid pin for left channel" msgstr "Pino inválido para canal esquerdo" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:88 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:151 msgid "Invalid pin for right channel" msgstr "Pino inválido para canal direito" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:91 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:154 msgid "Cannot output both channels on the same pin" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:176 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:243 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:189 #: ports/atmel-samd/common-hal/pulseio/PulseOut.c:110 +#: ports/nrf/common-hal/pulseio/PulseOut.c:107 msgid "All timers in use" msgstr "Todos os temporizadores em uso" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:285 msgid "All event channels in use" msgstr "Todos os canais de eventos em uso" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 +#: ports/atmel-samd/common-hal/audioio/AudioOut.c:375 #, c-format msgid "Sample rate too high. It must be less than %d" msgstr "Taxa de amostragem muito alta. Deve ser menor que %d" @@ -361,7 +362,7 @@ msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/SPI.c:132 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 -#: ports/nrf/common-hal/busio/I2C.c:81 +#: ports/nrf/common-hal/busio/I2C.c:82 msgid "Invalid pins" msgstr "Pinos inválidos" @@ -413,8 +414,8 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:120 #: ports/atmel-samd/common-hal/pulseio/PWMOut.c:369 -#: ports/nrf/common-hal/pulseio/PWMOut.c:120 -#: ports/nrf/common-hal/pulseio/PWMOut.c:232 +#: ports/nrf/common-hal/pulseio/PWMOut.c:119 +#: ports/nrf/common-hal/pulseio/PWMOut.c:233 msgid "Invalid PWM frequency" msgstr "Frequência PWM inválida" @@ -695,7 +696,131 @@ msgstr "parâmetro configuração desconhecido" msgid "AnalogOut functionality not supported" msgstr "Funcionalidade AnalogOut não suportada" -#: ports/nrf/common-hal/busio/I2C.c:95 +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Não é possível ajustar dados no pacote de anúncios." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parâmetro UUID inválido" + +#: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" @@ -731,112 +856,11 @@ msgstr "busio.UART não disponível" msgid "Can not get temperature. status: 0x%02x" msgstr "Não pode obter a temperatura. status: 0x%02x" -#: ports/nrf/common-hal/pulseio/PWMOut.c:162 +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 #, fuzzy msgid "All PWM peripherals are in use" msgstr "Todos os temporizadores em uso" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Não é possível aplicar parâmetros GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Não é possível definir parâmetros PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Não é possível consultar o endereço do dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Não é possível adicionar o serviço." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Não é possível adicionar Característica." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Não é possível aplicar o nome do dispositivo na pilha." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Pode codificar o UUID no pacote de anúncios." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Não é possível ajustar dados no pacote de anúncios." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Não é possível iniciar o anúncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Não pode parar propaganda. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Não é possível ler o valor do atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parâmetro UUID inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo de serviço inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Tipo desconhecido" @@ -1998,7 +2022,7 @@ msgid "AnalogOut is only 16 bits. Value must be less than 65536." msgstr "" #: shared-bindings/audiobusio/I2SOut.c:225 -#: shared-bindings/audioio/AudioOut.c:223 +#: shared-bindings/audioio/AudioOut.c:226 msgid "Not playing" msgstr "" @@ -2094,6 +2118,30 @@ msgstr "Número inválido de bits" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2208,7 +2256,7 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 -#: shared-bindings/pulseio/PulseOut.c:75 +#: shared-bindings/pulseio/PulseOut.c:76 msgid "Expected a %q" msgstr "Esperado um" @@ -2270,7 +2318,7 @@ msgstr "index deve ser int" msgid "Read-only" msgstr "Somente leitura" -#: shared-bindings/pulseio/PulseOut.c:134 +#: shared-bindings/pulseio/PulseOut.c:135 msgid "Array must contain halfwords (type 'H')" msgstr "Array deve conter meias palavras (tipo 'H')" @@ -2461,3 +2509,30 @@ msgstr "Muitos argumentos fornecidos com o formato dado" #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." + +#~ msgid "Can not add Service." +#~ msgstr "Não é possível adicionar o serviço." + +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 9f8993977..6b03d112d 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -41,13 +41,14 @@ INC += -I$(BUILD) INC += -I$(BUILD)/genhdr INC += -I./../../lib/cmsis/inc INC += -I./boards/$(BOARD) -INC += -I./bluetooth INC += -I./modules/ubluepy INC += -I./modules/ble INC += -I./nrfx INC += -I./nrfx/hal INC += -I./nrfx/mdk INC += -I./nrfx/drivers/include +INC += -I./bluetooth +INC += -I./peripherals INC += -I../../lib/mp-readline INC += -I../../lib/tinyusb/src INC += -I./usb @@ -103,8 +104,8 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ - drivers/bluetooth/ble_drv.c \ - drivers/bluetooth/ble_uart.c \ + bluetooth/ble_drv.c \ + bluetooth/ble_uart.c \ lib/libc/string0.c \ lib/mp-readline/readline.c \ lib/oofatfs/ff.c \ diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index dd2fd00dd..985e262e4 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -38,7 +38,7 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError, - "Soft device assert, id: 0x%08lX, pc: 0x%08lX", id, pc)); + translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc)); } STATIC uint32_t ble_stack_enable(void) { @@ -122,7 +122,7 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) { if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to change softdevice state, error: 0x%08lX", err_code)); + translate("Failed to change softdevice state, error: 0x%08lX"), err_code)); } } @@ -132,7 +132,7 @@ bool common_hal_bleio_adapter_get_enabled(void) { const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to get softdevice state, error: 0x%08lX", err_code)); + translate("Failed to get softdevice state, error: 0x%08lX"), err_code)); } return is_enabled; @@ -152,7 +152,7 @@ void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to get local address, error: 0x%08lX", err_code)); + translate("Failed to get local address, error: 0x%08lX"), err_code)); } address->type = local_address.addr_type; diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c index a370d29a7..246c35005 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -49,7 +49,7 @@ STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to write gatts value, status: 0x%08lX", err_code)); + translate("Failed to write gatts value, status: 0x%08lX"), err_code)); } } @@ -73,7 +73,7 @@ STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_i const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to notify attribute value, status: 0x%08lX", err_code)); + translate("Failed to notify attribute value, status: 0x%08lX"), err_code)); } m_tx_in_progress += 1; @@ -88,7 +88,7 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to read attribute value, status: 0x%08lX", err_code)); + translate("Failed to read attribute value, status: 0x%08lX"), err_code)); } while (m_read_characteristic != NULL) { @@ -116,14 +116,14 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_acquire(m_write_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to acquire mutex, status: 0x%08lX", err_code)); + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); } } err_code = sd_ble_gattc_write(device->conn_handle, &write_params); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to write attribute value, status: 0x%08lX", err_code)); + translate("Failed to write attribute value, status: 0x%08lX"), err_code)); } while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -135,7 +135,7 @@ STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_in err_code = sd_mutex_release(m_write_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to release mutex, status: 0x%08lX", err_code)); + translate("Failed to release mutex, status: 0x%08lX"), err_code)); } } diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c index c03db0ab9..2c000ae2e 100644 --- a/ports/nrf/common-hal/bleio/Device.c +++ b/ports/nrf/common-hal/bleio/Device.c @@ -78,7 +78,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta do { \ if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, \ - "Can not fit data into the advertisment packet")); \ + translate("Can not fit data into the advertisment packet"))); \ } \ adv_data[byte_pos] = (field); \ byte_pos += (len); \ @@ -111,7 +111,7 @@ STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connecta } else { if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Can not fit data into the advertisment packet")); + translate("Can not fit data into the advertisment packet"))); } memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len); @@ -263,13 +263,13 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to discover serivices, status: 0x%08lX", err_code)); + translate("Failed to discover serivices, status: 0x%08lX"), err_code)); } err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to acquire mutex, status: 0x%08lX", err_code)); + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -281,7 +281,7 @@ STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to release mutex, status: 0x%08lX", err_code)); + translate("Failed to release mutex, status: 0x%08lX"), err_code)); } return m_discovery_successful; @@ -304,7 +304,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_acquire(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to acquire mutex, status: 0x%08lX", err_code)); + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); } while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { @@ -316,7 +316,7 @@ STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_o err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to release mutex, status: 0x%08lX", err_code)); + translate("Failed to release mutex, status: 0x%08lX"), err_code)); } return m_discovery_successful; @@ -351,7 +351,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to release mutex, status: 0x%08lX", err_code)); + translate("Failed to release mutex, status: 0x%08lX"), err_code)); } } @@ -388,7 +388,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio const uint32_t err_code = sd_mutex_release(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to release mutex, status: 0x%08lX", err_code)); + translate("Failed to release mutex, status: 0x%08lX"), err_code)); } } @@ -400,7 +400,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to continue scanning, status: 0x%0xlX", err_code)); + translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); } #endif return; @@ -433,7 +433,7 @@ STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t * if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to connect, status: 0x%08lX", err_code)); + translate("Failed to connect, status: 0x%08lX"), err_code)); } } @@ -510,7 +510,7 @@ void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_servi const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to add service, status: 0x%08lX", err_code)); + translate("Failed to add service, status: 0x%08lX"), err_code)); } const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); @@ -528,7 +528,7 @@ void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool const uint32_t err_code = set_advertisement_data(device, connectable, raw_data); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to start advertisment, status: 0x%08lX", err_code)); + translate("Failed to start advertisment, status: 0x%08lX"), err_code)); } } @@ -546,7 +546,7 @@ void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to stop advertisment, status: 0x%08lX", err_code)); + translate("Failed to stop advertisment, status: 0x%08lX"), err_code)); } } @@ -572,7 +572,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to start scanning, status: 0x%0xlX", err_code)); + translate("Failed to start scanning, status: 0x%0xlX"), err_code)); } while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { @@ -589,7 +589,7 @@ void common_hal_bleio_device_connect(bleio_device_obj_t *device) { err_code = sd_mutex_new(m_discovery_mutex); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to create mutex, status: 0x%0xlX", err_code)); + translate("Failed to create mutex, status: 0x%0xlX"), err_code)); } } diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index 17af49621..e56c1860c 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -73,7 +73,7 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to continue scanning, status: 0x%0xlX", err_code)); + translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); } #endif } @@ -100,7 +100,7 @@ void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to start scanning, status: 0x%0xlX", err_code)); + translate("Failed to start scanning, status: 0x%0xlX"), err_code)); } if (timeout > 0) { diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c index ee2624073..c17c16904 100644 --- a/ports/nrf/common-hal/bleio/Service.c +++ b/ports/nrf/common-hal/bleio/Service.c @@ -80,7 +80,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to add characteristic, status: 0x%08lX", err_code)); + translate("Failed to add characteristic, status: 0x%08lX"), err_code)); } characteristic->user_desc_handle = handles.user_desc_handle; diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c index 891c34ac4..9a2e101ea 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -94,19 +94,19 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uui const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); if (err_code != NRF_SUCCESS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Failed to add Vendor Specific UUID, status: 0x%08lX", err_code)); + translate("Failed to add Vendor Specific UUID, status: 0x%08lX"), err_code)); } } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Invalid UUID string length")); + translate("Invalid UUID string length"))); } return; } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Invalid UUID parameter")); + translate("Invalid UUID parameter"))); } void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index 7ac42c740..ec23ff207 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -98,13 +98,13 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, i -= is_long ? 3 : 2; } } else { - mp_raise_ValueError("Wrong address length"); + mp_raise_ValueError(translate("Wrong address length")); } } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) { mp_buffer_info_t buf_info; mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); if (buf_info.len != BLEIO_ADDRESS_BYTES) { - mp_raise_ValueError("Wrong number of bytes provided"); + mp_raise_ValueError(translate("Wrong number of bytes provided")); } for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c index 3563d3895..369f3f991 100644 --- a/shared-bindings/bleio/Characteristic.c +++ b/shared-bindings/bleio/Characteristic.c @@ -122,7 +122,7 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t self->uuid = MP_OBJ_TO_PTR(uuid); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Invalid UUID parameter")); + translate("Invalid UUID parameter"))); } common_hal_bleio_characteristic_construct(self); diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c index 64cfb762f..94834ef7c 100644 --- a/shared-bindings/bleio/Device.c +++ b/shared-bindings/bleio/Device.c @@ -194,7 +194,7 @@ STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, self->address.type = scan_entry->address.type; memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES); } else { - self->name = mp_obj_new_str(default_name, strlen(default_name), false); + self->name = mp_obj_new_str(default_name, strlen(default_name)); common_hal_bleio_adapter_get_address(&self->address); } @@ -207,7 +207,7 @@ STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) if (!self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Can't add services in Central mode")); + translate("Can't add services in Central mode"))); } service->device = self; @@ -223,7 +223,7 @@ STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) { if (self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Can't connect in Peripheral mode")); + translate("Can't connect in Peripheral mode"))); } common_hal_bleio_device_connect(self); @@ -253,7 +253,7 @@ static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) { if (!self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Can't change the name in Central mode")); + translate("Can't change the name in Central mode"))); } self->name = value; @@ -274,7 +274,7 @@ STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t if (!self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Can't advertise in Central mode")); + translate("Can't advertise in Central mode"))); } enum { ARG_connectable, ARG_data }; @@ -310,7 +310,7 @@ STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) { if (!self->is_peripheral) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Can't advertise in Central mode")); + translate("Can't advertise in Central mode"))); } common_hal_bleio_device_stop_advertising(self); diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c index 2eed24cd8..e452c7267 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/bleio/ScanEntry.c @@ -177,7 +177,7 @@ STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) { return mp_const_none; } - return mp_obj_new_str((const char*)name, name_len - 1, false); + return mp_obj_new_str((const char*)name, name_len - 1); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name); diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c index 6e112880a..2d09cbc3c 100644 --- a/shared-bindings/bleio/Service.c +++ b/shared-bindings/bleio/Service.c @@ -102,7 +102,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, self->uuid = MP_OBJ_TO_PTR(uuid); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Invalid UUID parameter")); + translate("Invalid UUID parameter"))); } return MP_OBJ_FROM_PTR(self); -- cgit v1.2.3 From ec1aec1921c55b7570403b2958dc0a8170fe78ab Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 21 Oct 2018 10:22:00 -0500 Subject: shared-bindings/time: introduce time.monotonic_ns This is intended to be compatible with Python 3.7's time.monotonic_ns. The "actual resolution" is 1ms due to this being the unit at which common_hal_time_monotonic ticks. Closes #519 --- shared-bindings/time/__init__.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 4d9554569..8a5e16c5e 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -206,6 +206,20 @@ STATIC mp_obj_t time_time(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); +//| .. method:: monotonic_ns(clk_id) +//| +//| Return the time of the specified clock clk_id in nanoseconds. Refer to +//| Clock ID Constants for a list of accepted values for clk_id. +//| +//| :return: the current time +//| :rtype: int +//| +STATIC mp_obj_t time_monotonic_ns(void) { + uint64_t time64 = common_hal_time_monotonic() * 1000000llu; + return mp_obj_new_int_from_ll((long long) time64); +} +MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); + //| .. method:: localtime([secs]) //| //| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in @@ -280,6 +294,7 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = { #endif // MICROPY_PY_COLLECTIONS #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) }, + { MP_ROM_QSTR(MP_QSTR_monotonic_ns), MP_ROM_PTR(&time_monotonic_ns_obj) }, #endif }; -- cgit v1.2.3 From c16ef428ab31fbaeb6534e7ca56abb9591a2a6b7 Mon Sep 17 00:00:00 2001 From: Carlos Date: Sun, 21 Oct 2018 11:38:16 -0500 Subject: [locale\es.po] Address @sabas1080 recommendations --- locale/es.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/es.po b/locale/es.po index 59b8d6353..a7f7e6738 100644 --- a/locale/es.po +++ b/locale/es.po @@ -169,7 +169,7 @@ msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n" #: main.c:161 main.c:232 msgid "Auto-reload is off.\n" -msgstr "Auto-recarga deshabilitado.\n" +msgstr "Auto-recarga deshabilitada.\n" #: main.c:175 msgid "Running in safe mode! Not running saved code.\n" @@ -400,7 +400,7 @@ msgstr "Ha fallado la asignación del buffer RX" #: ports/atmel-samd/common-hal/busio/UART.c:153 msgid "Could not initialize UART" -msgstr "No se pudo inicializar la UART" +msgstr "No se puede inicializar la UART" #: ports/atmel-samd/common-hal/busio/UART.c:240 #: ports/nrf/common-hal/busio/UART.c:149 @@ -1344,7 +1344,7 @@ msgstr "Operacion no soportada" #: py/moduerrno.c:149 msgid "Invalid argument" -msgstr "argumento inválido" +msgstr "Argumento inválido" #: py/obj.c:90 msgid "Traceback (most recent call last):\n" -- cgit v1.2.3 From 71ac9d16a7b2cb9d5ec758b4cd6fdcf3ec22184b Mon Sep 17 00:00:00 2001 From: Carlos Date: Sun, 21 Oct 2018 11:56:05 -0500 Subject: [locale\es.po] Add missing \n --- locale/es.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/es.po b/locale/es.po index a7f7e6738..d4570cb09 100644 --- a/locale/es.po +++ b/locale/es.po @@ -210,7 +210,7 @@ msgstr "" msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" -msgstr "La alimentación del microcontrolador cayó. Por favor asegurate de que tu fuente de alimentación provee" +msgstr "La alimentación del microcontrolador cayó. Por favor asegurate de que tu fuente de alimentación provee\n" #: main.c:256 msgid "" -- cgit v1.2.3 From f0d7073a12d6a945eaff4f55920d66a3f8f06192 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Mon, 22 Oct 2018 19:38:24 -0500 Subject: Add Arduino MKR1300 --- ports/atmel-samd/boards/arduino_mkr1300/board.c | 40 ++++++++++++++++++++ .../boards/arduino_mkr1300/mpconfigboard.h | 26 +++++++++++++ .../boards/arduino_mkr1300/mpconfigboard.mk | 11 ++++++ ports/atmel-samd/boards/arduino_mkr1300/pins.c | 44 ++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 ports/atmel-samd/boards/arduino_mkr1300/board.c create mode 100644 ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/arduino_mkr1300/pins.c diff --git a/ports/atmel-samd/boards/arduino_mkr1300/board.c b/ports/atmel-samd/boards/arduino_mkr1300/board.c new file mode 100644 index 000000000..770bc8259 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h new file mode 100644 index 000000000..ad9dc43b4 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h @@ -0,0 +1,26 @@ +#define MICROPY_HW_BOARD_NAME "Arduino MKR1300" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#include "internal_flash.h" + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA15) + +#define DEFAULT_UART_BUS_RX (&pin_PB23) +#define DEFAULT_UART_BUS_TX (&pin_PB22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk new file mode 100644 index 000000000..071f7e64c --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x2341 +USB_PID = 0x8053 +USB_PRODUCT = "Arduino MKR1300" +USB_MANUFACTURER = "Arduino" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/pins.c b/ports/atmel-samd/boards/arduino_mkr1300/pins.c new file mode 100644 index 000000000..de9f9769c --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/pins.c @@ -0,0 +1,44 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_PB09) }, // NOTE: LORA BOOT + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_RST), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); -- cgit v1.2.3 From 37d784bcdc9e1cfb809a66ca8f5aafee0d86e089 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Mon, 22 Oct 2018 19:42:40 -0500 Subject: add auto-built by Travis mkr1300 --- .travis.yml | 2 +- tools/build_adafruit_bins.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6cfa869b0..e7ef24916 100755 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ git: env: - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow arduino_mkr1300" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express" TRAVIS_SDK=arm diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 291a1d46e..9f18e9d88 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -7,6 +7,7 @@ rm -rf ports/nrf/build* # Alphabetical. HW_BOARDS="\ arduino_zero \ +arduino_mkr1300 \ circuitplayground_express \ circuitplayground_express_crickit \ feather_huzzah \ -- cgit v1.2.3 From 59e43a2be4e740b65ae19b708c8e9670fa04fc05 Mon Sep 17 00:00:00 2001 From: Joshua Lowe Date: Tue, 23 Oct 2018 16:05:07 +0100 Subject: Update README to include Hallowing --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index ac74f10d6..1364ba6b2 100644 --- a/README.rst +++ b/README.rst @@ -37,6 +37,7 @@ Designed for CircuitPython - `Adafruit ItsyBitsy M0 Express `_ (`CircuitPython Guide `__) - `Adafruit Trinket M0 `__ (`CircuitPython Guide `__) - `Adafruit Metro M4 `__ (`CircuitPython Guide `__) +- `Adafruit Hallowing M0 Express `__ (`CircuitPython Guide `__) Other ~~~~~ -- cgit v1.2.3 From 41f62d84cb157bdaf612ec2da80afabd60d7a98f Mon Sep 17 00:00:00 2001 From: Joshua Lowe Date: Tue, 23 Oct 2018 17:27:54 +0100 Subject: Update README.rst --- README.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 1364ba6b2..a9b82bbe6 100644 --- a/README.rst +++ b/README.rst @@ -30,14 +30,19 @@ Supported Boards Designed for CircuitPython ~~~~~~~~~~~~~~~~~~~~~~~~~~ +**M0 Boards** - `Adafruit CircuitPlayground Express `__ (`CircuitPython Guide `__) - `Adafruit Feather M0 Express `__ (`CircuitPython Guide `__) -- `Adafruit Metro M0 Express `_ (`CircuitPython Guide `__) - `Adafruit Gemma M0 `__ (`CircuitPython Guide `__) +- `Adafruit Hallowing M0 Express `__ (`CircuitPython Guide `__) - `Adafruit ItsyBitsy M0 Express `_ (`CircuitPython Guide `__) +- `Adafruit Metro M0 Express `_ (`CircuitPython Guide `__) - `Adafruit Trinket M0 `__ (`CircuitPython Guide `__) + +**M4 Boards** +- `Adafruit Feather M4 Express `__ (`CircuitPython Guide `__) +- `Adafruit ItsyBitsy M4 Express `__ (`CircuitPython Guide `__) - `Adafruit Metro M4 `__ (`CircuitPython Guide `__) -- `Adafruit Hallowing M0 Express `__ (`CircuitPython Guide `__) Other ~~~~~ -- cgit v1.2.3 From cb47d9edee687aa67195ddc949ff8c52cfb87881 Mon Sep 17 00:00:00 2001 From: Joshua Lowe Date: Tue, 23 Oct 2018 17:28:30 +0100 Subject: Update README.rst --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index a9b82bbe6..410f6cf8a 100644 --- a/README.rst +++ b/README.rst @@ -31,6 +31,7 @@ Designed for CircuitPython ~~~~~~~~~~~~~~~~~~~~~~~~~~ **M0 Boards** + - `Adafruit CircuitPlayground Express `__ (`CircuitPython Guide `__) - `Adafruit Feather M0 Express `__ (`CircuitPython Guide `__) - `Adafruit Gemma M0 `__ (`CircuitPython Guide `__) @@ -40,6 +41,7 @@ Designed for CircuitPython - `Adafruit Trinket M0 `__ (`CircuitPython Guide `__) **M4 Boards** + - `Adafruit Feather M4 Express `__ (`CircuitPython Guide `__) - `Adafruit ItsyBitsy M4 Express `__ (`CircuitPython Guide `__) - `Adafruit Metro M4 `__ (`CircuitPython Guide `__) -- cgit v1.2.3 From 1936cd3f386e78cdd0d566fb3d5e7aa047ca7d48 Mon Sep 17 00:00:00 2001 From: Joshua Lowe Date: Tue, 23 Oct 2018 17:30:53 +0100 Subject: Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 410f6cf8a..f3ee34f34 100644 --- a/README.rst +++ b/README.rst @@ -44,7 +44,7 @@ Designed for CircuitPython - `Adafruit Feather M4 Express `__ (`CircuitPython Guide `__) - `Adafruit ItsyBitsy M4 Express `__ (`CircuitPython Guide `__) -- `Adafruit Metro M4 `__ (`CircuitPython Guide `__) +- `Adafruit Metro M4 `__ (`CircuitPython Guide `__) Other ~~~~~ -- cgit v1.2.3 From e02811054e726cae590938b111ffcf640c0b3704 Mon Sep 17 00:00:00 2001 From: Joshua Lowe Date: Tue, 23 Oct 2018 18:17:50 +0100 Subject: Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f3ee34f34..e89543fe5 100644 --- a/README.rst +++ b/README.rst @@ -44,7 +44,7 @@ Designed for CircuitPython - `Adafruit Feather M4 Express `__ (`CircuitPython Guide `__) - `Adafruit ItsyBitsy M4 Express `__ (`CircuitPython Guide `__) -- `Adafruit Metro M4 `__ (`CircuitPython Guide `__) +- `Adafruit Metro M4 Express `__ (`CircuitPython Guide `__) Other ~~~~~ -- cgit v1.2.3 From fbadfd599810cb1ebc93e4915f5b6d63cecbc75a Mon Sep 17 00:00:00 2001 From: Senuros Date: Wed, 24 Oct 2018 11:39:16 +0200 Subject: added more german translation strings, fixed some existing translation strings --- locale/de_DE.po | 76 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/locale/de_DE.po b/locale/de_DE.po index de9a21e96..0f8aee846 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -93,7 +93,7 @@ msgstr "struct: index außerhalb gültigen Bereichs" #: extmod/moduheapq.c:38 msgid "heap must be a list" -msgstr "heap muss eine list sein" +msgstr "heap muss eine Liste sein" #: extmod/moduheapq.c:86 extmod/modutimeq.c:147 extmod/modutimeq.c:172 msgid "empty heap" @@ -185,12 +185,12 @@ msgstr "Du hast das Starten im Sicherheitsmodus ausgelöst durch " #: main.c:242 msgid "To exit, please reset the board without " -msgstr "Zum beenden bitte resete das board ohne " +msgstr "Zum beenden bitte resette das board ohne " #: main.c:249 msgid "" "You are running in safe mode which means something really bad happened.\n" -msgstr "Sicherheitsmodus aktive, etwas wirklich schlechtes ist passiert.\n" +msgstr "Sicherheitsmodus aktiv, etwas wirklich schlechtes ist passiert.\n" #: main.c:251 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" @@ -215,7 +215,7 @@ msgid "" "CIRCUITPY).\n" msgstr "" "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach " -"demsicheren Auswerfen von CIRCUITPY.)\n" +"dem sicheren Auswerfen von CIRCUITPY.)\n" #: main.c:260 msgid "Press any key to enter the REPL. Use CTRL-D to reload." @@ -225,7 +225,7 @@ msgstr "" #: main.c:416 msgid "soft reboot\n" -msgstr "weicher reboot\n" +msgstr "soft reboot\n" #: ports/atmel-samd/audio_dma.c:209 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:361 @@ -268,7 +268,7 @@ msgstr "AnalogOut ist an diesem Pin nicht unterstützt" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:147 #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:150 msgid "Invalid bit clock pin" -msgstr "Ungülgites bit clock pin" +msgstr "Ungültiges bit clock pin" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:153 msgid "Bit clock and word select must share a clock unit" @@ -284,7 +284,7 @@ msgstr "Ungültiger data pin" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:145 #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c:150 msgid "Serializer in use" -msgstr "Serilaizer wird benutzt" +msgstr "Serializer wird benutzt" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c:230 msgid "Clock unit in use" @@ -355,7 +355,7 @@ msgstr "Alle timer werden benutzt" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:218 msgid "All event channels in use" -msgstr "Alle event Kanälre werden benutzt" +msgstr "Alle event Kanäle werden benutzt" #: ports/atmel-samd/common-hal/audioio/AudioOut.c:297 #, c-format @@ -380,7 +380,7 @@ msgstr "SDA oder SCL brauchen pull up" #: ports/atmel-samd/common-hal/busio/I2C.c:121 msgid "Unsupported baudrate" -msgstr "Baudrate wird nicht unterstütz" +msgstr "Baudrate wird nicht unterstützt" #: ports/atmel-samd/common-hal/busio/UART.c:66 msgid "bytes > 8 bits not supported" @@ -545,24 +545,24 @@ msgstr "Minimale PWM Frequenz ist %dHz" #: ports/esp8266/common-hal/pulseio/PWMOut.c:68 #, c-format msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." -msgstr "" +msgstr "Mehrere PWM Frequenzen nicht unterstützt. PWM bereits auf %dHz gesetzt." #: ports/esp8266/common-hal/pulseio/PWMOut.c:77 ports/esp8266/machine_pwm.c:70 #, c-format msgid "PWM not supported on pin %d" -msgstr "" +msgstr "PWM nicht unterstützt an Pin %d" #: ports/esp8266/common-hal/pulseio/PulseIn.c:78 msgid "No PulseIn support for %q" -msgstr "" +msgstr "Keine PulseIn Unterstützung für %q" #: ports/esp8266/common-hal/storage/__init__.c:34 msgid "Unable to remount filesystem" -msgstr "" +msgstr "Dateisystem kann nicht wieder gemounted werden." #: ports/esp8266/common-hal/storage/__init__.c:38 msgid "Use esptool to erase flash and re-upload Python instead" -msgstr "" +msgstr "Benutze esptool um den flash zu löschen und stattdessen Python hochzuladen" #: ports/esp8266/esp_mphal.c:154 msgid "C-level assert" @@ -571,102 +571,102 @@ msgstr "" #: ports/esp8266/machine_adc.c:57 #, c-format msgid "not a valid ADC Channel: %d" -msgstr "" +msgstr "Kein gültiger ADC Kanal: %d" #: ports/esp8266/machine_hspi.c:131 ports/esp8266/machine_hspi.c:137 msgid "impossible baudrate" -msgstr "" +msgstr "Unmögliche Baudrate" #: ports/esp8266/machine_pin.c:129 msgid "expecting a pin" -msgstr "" +msgstr "Ein Pin wird erwartet" #: ports/esp8266/machine_pin.c:284 msgid "Pin(16) doesn't support pull" -msgstr "" +msgstr "Pin(16) unterstützt kein pull" #: ports/esp8266/machine_pin.c:323 msgid "invalid pin" -msgstr "" +msgstr "Ungültiger Pin" #: ports/esp8266/machine_pin.c:389 msgid "pin does not have IRQ capabilities" -msgstr "" +msgstr "Pin hat keine IRQ Fähigkeiten" #: ports/esp8266/machine_rtc.c:185 msgid "buffer too long" -msgstr "" +msgstr "Buffer zu lang" #: ports/esp8266/machine_rtc.c:209 ports/esp8266/machine_rtc.c:223 #: ports/esp8266/machine_rtc.c:246 msgid "invalid alarm" -msgstr "" +msgstr "Ungültiger Alarm" #: ports/esp8266/machine_uart.c:169 #, c-format msgid "UART(%d) does not exist" -msgstr "" +msgstr "UART(%d) existiert nicht" #: ports/esp8266/machine_uart.c:219 msgid "UART(1) can't read" -msgstr "" +msgstr "UART(1) kann nicht lesen" #: ports/esp8266/modesp.c:119 msgid "len must be multiple of 4" -msgstr "" +msgstr "len muss ein vielfaches von 4 sein" #: ports/esp8266/modesp.c:274 #, c-format msgid "memory allocation failed, allocating %u bytes for native code" -msgstr "" +msgstr "Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code" #: ports/esp8266/modesp.c:317 msgid "flash location must be below 1MByte" -msgstr "" +msgstr "flash location muss unter 1MByte sein" #: ports/esp8266/modmachine.c:63 msgid "frequency can only be either 80Mhz or 160MHz" -msgstr "" +msgstr "Die Frequenz kann nur 80Mhz oder 160Mhz sein" #: ports/esp8266/modnetwork.c:61 msgid "AP required" -msgstr "" +msgstr "AP erforderlich" #: ports/esp8266/modnetwork.c:61 msgid "STA required" -msgstr "" +msgstr "STA erforderlich" #: ports/esp8266/modnetwork.c:87 msgid "Cannot update i/f status" -msgstr "" +msgstr "Kann i/f Status nicht updaten" #: ports/esp8266/modnetwork.c:142 msgid "Cannot set STA config" -msgstr "" +msgstr "Kann STA Konfiguration nicht setzen" #: ports/esp8266/modnetwork.c:144 msgid "Cannot connect to AP" -msgstr "" +msgstr "Kann nicht zu AP verbinden" #: ports/esp8266/modnetwork.c:152 msgid "Cannot disconnect from AP" -msgstr "" +msgstr "Kann nicht trennen von AP" #: ports/esp8266/modnetwork.c:173 msgid "unknown status param" -msgstr "" +msgstr "Unbekannter Statusparameter" #: ports/esp8266/modnetwork.c:222 msgid "STA must be active" -msgstr "" +msgstr "STA muss aktiv sein" #: ports/esp8266/modnetwork.c:239 msgid "scan failed" -msgstr "" +msgstr "Scan fehlgeschlagen" #: ports/esp8266/modnetwork.c:306 msgid "wifi_set_ip_info() failed" -msgstr "" +msgstr "wifi_set_ip_info() fehlgeschlagen" #: ports/esp8266/modnetwork.c:319 msgid "either pos or kw args are allowed" -- cgit v1.2.3 From cec9a69a15a16a42bea528032d00684ddee0df22 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sun, 7 Oct 2018 19:51:24 +0200 Subject: samd51: Make errno, os, and time module aliases Add alias for uerrno so the user doesn't have to know about the CircuitPython special names for the module. Make os and time weak modules (aliases) making it possible to add functionality to those modules written in python. Example: 'import os' will now look in the path for an os module and if not found it will import the builtin module. An os module written in python will import the builtin module through its name prefixed with an underscore (_os) following the C module naming practice in CPython. Also right align the macro values to increase readability making it easier to compare the values for samd21 and samd51. Even the longest macro from py/mpconfig.h will fit with this alignment. --- ports/atmel-samd/mpconfigport.h | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 14f72ccfb..afdbf0cd8 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -84,7 +84,6 @@ #define MICROPY_VFS (1) #define MICROPY_VFS_FAT (1) #define MICROPY_PY_MACHINE (1) -#define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_ENABLE_FINALISER (1) @@ -140,15 +139,17 @@ typedef long mp_off_t; #include "include/sam.h" #ifdef SAMD21 -#define CIRCUITPY_MCU_FAMILY samd21 +#define CIRCUITPY_MCU_FAMILY samd21 #define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" -#define PORT_HEAP_SIZE (16384 + 4096) +#define PORT_HEAP_SIZE (16384 + 4096) +#define MICROPY_MODULE_WEAK_LINKS (0) #endif #ifdef SAMD51 -#define CIRCUITPY_MCU_FAMILY samd51 +#define CIRCUITPY_MCU_FAMILY samd51 #define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" -#define PORT_HEAP_SIZE (0x20000) // 128KiB +#define PORT_HEAP_SIZE (0x20000) // 128KiB +#define MICROPY_MODULE_WEAK_LINKS (1) #endif #ifdef LONGINT_IMPL_NONE @@ -290,6 +291,33 @@ extern const struct _mp_obj_module_t usb_hid_module; { MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, +#elif MICROPY_MODULE_WEAK_LINKS +#define MICROPY_PORT_BUILTIN_MODULES \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR__os), (mp_obj_t)&os_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_rtc), (mp_obj_t)&rtc_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_samd),(mp_obj_t)&samd_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ + TOUCHIO_MODULE \ + EXTRA_BUILTIN_MODULES + +#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ + { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, \ + { MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&os_module) }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ + #else #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ -- cgit v1.2.3 From 1b86e5fc8362a913a0ef7de01cce68c980238fd8 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sun, 7 Oct 2018 20:43:39 +0200 Subject: samd51: Enable functionality to support CPython stdlib This enables various things in order to support the CPython standard library. MICROPY_PY_BUILTINS_NOTIMPLEMENTED: Support NotImplemented for easy conversion of stdlib. It doesn't do fallbacks though, only raises TypeError. MICROPY_PY_COLLECTIONS_ORDEREDDICT: collections.OrderedDict MICROPY_PY_FUNCTION_ATTRS: Support function.__name__ for use as key in the function attribute workaround. MICROPY_PY_IO: uio module: BytesIO, FileIO, StringIO, TextIOWrapper Also add 'io' alias. MICROPY_PY_REVERSE_SPECIAL_METHODS: Support the __r*__ special methods. MICROPY_PY_SYS_EXC_INFO: sys.exc_info() used by unittest when collecting exceptions. MICROPY_CPYTHON_COMPAT: Some of the things it adds: >>> object.__init__ >>> object.__new__ >>> object.__class__ >>> object().__class__ >>> object.__name__ 'object' >>> 'Hello'.encode() b'Hello' >>> b'Hello'.decode() 'Hello' Named tuple field names from string: namedtuple('Point', 'x y') --- ports/atmel-samd/mpconfigport.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index afdbf0cd8..38eabf748 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -20,8 +20,6 @@ #define MICROPY_COMP_CONST (1) #define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) #define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) -// Turn off for consistency -#define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (0) #define MICROPY_ENABLE_GC (1) @@ -57,7 +55,6 @@ #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) -#define MICROPY_PY_IO (0) #define MICROPY_PY_URANDOM (0) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) #define MICROPY_PY_STRUCT (0) @@ -142,14 +139,28 @@ typedef long mp_off_t; #define CIRCUITPY_MCU_FAMILY samd21 #define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" #define PORT_HEAP_SIZE (16384 + 4096) +#define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_MODULE_WEAK_LINKS (0) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) +#define MICROPY_PY_FUNCTION_ATTRS (0) +#define MICROPY_PY_IO (0) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) +#define MICROPY_PY_SYS_EXC_INFO (0) #endif #ifdef SAMD51 #define CIRCUITPY_MCU_FAMILY samd51 #define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" #define PORT_HEAP_SIZE (0x20000) // 128KiB +#define MICROPY_CPYTHON_COMPAT (1) #define MICROPY_MODULE_WEAK_LINKS (1) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_SYS_EXC_INFO (1) #endif #ifdef LONGINT_IMPL_NONE @@ -315,6 +326,7 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, \ + { MP_ROM_QSTR(MP_QSTR_io), MP_ROM_PTR(&mp_module_io) }, \ { MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&os_module) }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ -- cgit v1.2.3 From d882ff6328f0c0afee75f202ca7a87ffad252b8b Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sun, 7 Oct 2018 21:54:53 +0200 Subject: samd51: Set stack size to 8k This is necessary in order to run unittest. Heavy tests like those in the stdlib need 12-14k. --- ports/atmel-samd/mpconfigport.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 38eabf748..7b54a418d 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -139,6 +139,7 @@ typedef long mp_off_t; #define CIRCUITPY_MCU_FAMILY samd21 #define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" #define PORT_HEAP_SIZE (16384 + 4096) +#define CIRCUITPY_DEFAULT_STACK_SIZE 4096 #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) @@ -153,6 +154,7 @@ typedef long mp_off_t; #define CIRCUITPY_MCU_FAMILY samd51 #define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" #define PORT_HEAP_SIZE (0x20000) // 128KiB +#define CIRCUITPY_DEFAULT_STACK_SIZE 8192 #define MICROPY_CPYTHON_COMPAT (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) @@ -400,8 +402,4 @@ void run_background_tasks(void); #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 #define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt" -// TODO(tannewt): Make this 6k+ for any non-express M4 boards because they cache sectors on the -// stack. -#define CIRCUITPY_DEFAULT_STACK_SIZE 4096 - #endif // __INCLUDED_MPCONFIGPORT_H -- cgit v1.2.3 From b714f5d650b53aff9fc5bc4efe1bf43eddfc7c24 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 25 Oct 2018 11:29:27 +1100 Subject: Add "dhcp" property to turn DHCP on and off --- shared-bindings/wiznet/wiznet5k.c | 41 ++++++++++++++++++++++++++++++++++----- shared-module/wiznet/wiznet5k.c | 10 ++++++---- shared-module/wiznet/wiznet5k.h | 4 ++++ 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index e1076bc15..4e5fff869 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -66,17 +66,17 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size return wiznet5k_create(args[0], args[1], args[2]); } +//| .. attribute:: connected +//| +//| is this device physically connected? +//| + STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { (void)self_in; return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); -//| .. attribute:: connected -//| -//| is this device physically connected? -//| - const mp_obj_property_t wiznet5k_connected_obj = { .base.type = &mp_type_property, .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, @@ -84,6 +84,36 @@ const mp_obj_property_t wiznet5k_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: dhcp +//| +//| is DHCP active on this device? (set to true to activate DHCP, false to turn it off) +//| + +STATIC mp_obj_t wiznet5k_dhcp_get_value(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wiznet5k_check_dhcp()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_dhcp_get_value_obj, wiznet5k_dhcp_get_value); + +STATIC mp_obj_t wiznet5k_dhcp_set_value(mp_obj_t self_in, mp_obj_t value) { + (void)self_in; + if (mp_obj_is_true(value)) { + wiznet5k_start_dhcp(); + } else { + wiznet5k_stop_dhcp(); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_dhcp_set_value_obj, wiznet5k_dhcp_set_value); + +const mp_obj_property_t wiznet5k_dhcp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_dhcp_get_value_obj, + (mp_obj_t)&wiznet5k_dhcp_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. method:: ifconfig(...) //| //| Called without parameters, returns a tuple of @@ -121,6 +151,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_dhcp), MP_ROM_PTR(&wiznet5k_dhcp_obj) }, }; STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 4bf536226..ee732859a 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -324,7 +324,7 @@ void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) { } } -static void wiznet5k_start_dhcp(void) { +void wiznet5k_start_dhcp(void) { static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; if (!wiznet5k_obj.dhcp_active) { @@ -335,15 +335,17 @@ static void wiznet5k_start_dhcp(void) { } } -#if 0 -static void wiznet5k_stop_dhcp(void) { +void wiznet5k_stop_dhcp(void) { if (wiznet5k_obj.dhcp_active) { wiznet5k_obj.dhcp_active = 0; DHCP_stop(); WIZCHIP_EXPORT(close)(0); } } -#endif + +bool wiznet5k_check_dhcp(void) { + return wiznet5k_obj.dhcp_active; +} /// Create and return a WIZNET5K object. mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h index 04b8872fb..1284a44fd 100644 --- a/shared-module/wiznet/wiznet5k.h +++ b/shared-module/wiznet/wiznet5k.h @@ -60,6 +60,10 @@ void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket); mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); +void wiznet5k_start_dhcp(void); +void wiznet5k_stop_dhcp(void); +bool wiznet5k_check_dhcp(void); + extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; #endif // MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H -- cgit v1.2.3 From c9279e8d3a4ee2a397cc1c5c9bf5bbc30a4c5216 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 25 Oct 2018 12:54:39 +1100 Subject: Update translations --- locale/circuitpython.pot | 2 +- locale/fr.po | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a75f2169b..b389ec24a 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-10-25 12:53+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr.po b/locale/fr.po index 95aeef5e2..580b4809c 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-10-25 12:53+1100\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -2523,10 +2523,10 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" - #, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "'len' doit être un multiple de 4" + +#, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "la palette doit être longue de 32 octets" -- cgit v1.2.3 From bbf833416687c5b52695e1769cb4816256bf62d9 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 25 Oct 2018 13:13:08 +1100 Subject: Fix build without network code --- ports/atmel-samd/background.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 385f0c284..3cf6831a3 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -42,7 +42,7 @@ void run_background_tasks(void) { #ifdef CIRCUITPY_DISPLAYIO displayio_refresh_display(); #endif - #ifdef MICROPY_PY_NETWORK + #if MICROPY_PY_NETWORK network_module_background(); #endif usb_msc_background(); -- cgit v1.2.3 From ba98d4ce9c98b5cdfd675bfae01b65625f66c678 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Thu, 25 Oct 2018 16:11:49 -0500 Subject: minor changes in auto-built --- .travis.yml | 4 ++-- tools/build_adafruit_bins.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7ef24916..5b68138f5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,8 @@ git: env: - TRAVIS_TESTS="unix docs translations" TRAVIS_BOARDS="feather_huzzah circuitplayground_express pca10056 pca10059 feather_nrf52832 feather_nrf52840_express" TRAVIS_SDK=arm:nrf:esp8266 - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow arduino_mkr1300" TRAVIS_SDK=arm - - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm + - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300" TRAVIS_SDK=arm - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express" TRAVIS_SDK=arm addons: diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 9f18e9d88..60b1fb0d1 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -6,8 +6,8 @@ rm -rf ports/nrf/build* # Alphabetical. HW_BOARDS="\ -arduino_zero \ arduino_mkr1300 \ +arduino_zero \ circuitplayground_express \ circuitplayground_express_crickit \ feather_huzzah \ -- cgit v1.2.3 From 7a144413d14a75b5e6d954329d24b675c0f2d4ee Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Thu, 25 Oct 2018 17:37:59 -0500 Subject: Add "third-party" or "non-Adafruit" boards to README --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index ac74f10d6..3a9514f62 100644 --- a/README.rst +++ b/README.rst @@ -53,6 +53,12 @@ Other library `__) - `Arduino Zero `__ +"Third-party" or "non-Adafruit" boards +~~~~~ + +- `Electronic Cats Meow Meow `__ + + Download -------- -- cgit v1.2.3 From 893bde1f78f15a8a7f901e0d410637d3fdccb216 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 26 Oct 2018 11:35:55 -0700 Subject: Longer underline --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 3a9514f62..16b42e5e2 100644 --- a/README.rst +++ b/README.rst @@ -54,7 +54,7 @@ Other - `Arduino Zero `__ "Third-party" or "non-Adafruit" boards -~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - `Electronic Cats Meow Meow `__ -- cgit v1.2.3 From c7deb37d36507e71e3b2db4058987077a55da453 Mon Sep 17 00:00:00 2001 From: MCHobby Date: Sun, 28 Oct 2018 14:46:33 +0100 Subject: update fr.po Add some French translation --- locale/fr.po | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index 580b4809c..b7f3f8a6e 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -2188,7 +2188,7 @@ msgstr "La longueur doit être entière" #: shared-bindings/displayio/FourWire.c:55 #: shared-bindings/displayio/FourWire.c:64 msgid "displayio is a work in progress" -msgstr "" +msgstr "displayio est en cours de développement" #: shared-bindings/displayio/Group.c:65 #, fuzzy @@ -2204,7 +2204,7 @@ msgstr "" #: shared-bindings/displayio/Palette.c:102 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" +msgstr "Le tampon couleur doit avoir 3 octets (RVB) ou 4 octets (RVB + octet de padding)" #: shared-bindings/displayio/Palette.c:106 #, fuzzy @@ -2251,11 +2251,11 @@ msgstr "ne peut convertir %s en entier int" #: shared-bindings/i2cslave/I2CSlave.c:101 msgid "address out of bounds" -msgstr "" +msgstr "Adresse hors limite" #: shared-bindings/i2cslave/I2CSlave.c:107 msgid "addresses is empty" -msgstr "" +msgstr "Adresses est vide" #: shared-bindings/microcontroller/Pin.c:89 #: shared-bindings/neopixel_write/__init__.c:67 @@ -2358,7 +2358,7 @@ msgstr "calibration de la RTC non supportée sur cette carte" #: shared-bindings/socket/__init__.c:516 shared-module/network/__init__.c:81 #, fuzzy msgid "no available NIC" -msgstr "busio.UART n'est pas disponible" +msgstr "NIC non disponible" #: shared-bindings/storage/__init__.c:77 msgid "filesystem must provide mount method" @@ -2417,7 +2417,7 @@ msgstr "Impossible d'allouer le 2e tampon" #: shared-module/audioio/Mixer.c:82 msgid "Voice index too high" -msgstr "" +msgstr "Index de la voix trop grand" #: shared-module/audioio/Mixer.c:85 msgid "The sample's sample rate does not match the mixer's" @@ -2429,11 +2429,11 @@ msgstr "" #: shared-module/audioio/Mixer.c:91 msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" +msgstr "Le bits_per_sample de l'échantillon ne correspond pas au mixer" #: shared-module/audioio/Mixer.c:100 msgid "The sample's signedness does not match the mixer's" -msgstr "" +msgstr "L'échantillon non signé ne correspond pas au mixer" #: shared-module/audioio/WaveFile.c:61 msgid "Invalid wave file" @@ -2485,7 +2485,7 @@ msgstr "Pas de transfert sans broches MOSI et MISO" #: shared-module/displayio/Bitmap.c:49 msgid "Only bit maps of 8 bit color or less are supported" -msgstr "" +msgstr "Seul les mappings en couleur 8 bits (ou moins) sont supportés" #: shared-module/displayio/Bitmap.c:69 msgid "row must be packed and word aligned" @@ -2493,12 +2493,12 @@ msgstr "" #: shared-module/displayio/Group.c:39 msgid "Group full" -msgstr "" +msgstr "Group complet" #: shared-module/displayio/Group.c:48 #, fuzzy msgid "Group empty" -msgstr "vide" +msgstr "Groupe vide" #: shared-module/displayio/OnDiskBitmap.c:49 #, fuzzy @@ -2508,12 +2508,12 @@ msgstr "Fichier invalide" #: shared-module/displayio/OnDiskBitmap.c:59 #, c-format msgid "Only Windows format, uncompressed BMP supported %d" -msgstr "" +msgstr "Seul le format Windows, BMP non compressé, est supporté %d" #: shared-module/displayio/OnDiskBitmap.c:64 #, c-format msgid "Only true color (24 bpp or higher) BMP supported %x" -msgstr "" +msgstr "Seul les BMP 'true color' (24 bpp ou plus) sont supportés %x" #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" @@ -2525,8 +2525,8 @@ msgstr "trop d'arguments fournis avec ce format" #, fuzzy #~ msgid "value_size must be power of two" -#~ msgstr "'len' doit être un multiple de 4" +#~ msgstr "value_size est une puissance de deux" #, fuzzy #~ msgid "palette must be displayio.Palette" -#~ msgstr "la palette doit être longue de 32 octets" +#~ msgstr "palettre doit être displayio.Palette" -- cgit v1.2.3 From 1a3d467ba48196764bc45c0b9bae2ea89d5821b0 Mon Sep 17 00:00:00 2001 From: Retoc Date: Wed, 31 Oct 2018 00:41:11 +0100 Subject: added more german translations --- locale/de_DE.po | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/locale/de_DE.po b/locale/de_DE.po index 11cac7110..f633c93a4 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -753,112 +753,112 @@ msgstr "Alle timer werden benutzt" #: ports/nrf/drivers/bluetooth/ble_drv.c:199 msgid "Cannot apply GAP parameters." -msgstr "" +msgstr "Kann GAP Parameter nicht anwenden." #: ports/nrf/drivers/bluetooth/ble_drv.c:213 msgid "Cannot set PPCP parameters." -msgstr "" +msgstr "Kann PPCP Parameter nicht setzen." #: ports/nrf/drivers/bluetooth/ble_drv.c:245 msgid "Can not query for the device address." -msgstr "" +msgstr "Kann nicht nach der Geräteadresse suchen." #: ports/nrf/drivers/bluetooth/ble_drv.c:264 msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "" +msgstr "Kann keine herstellerspezifische 128-Bit-UUID hinzufügen." #: ports/nrf/drivers/bluetooth/ble_drv.c:284 #: ports/nrf/drivers/bluetooth/ble_drv.c:298 msgid "Can not add Service." -msgstr "" +msgstr "Kann den Dienst nicht hinzufügen." #: ports/nrf/drivers/bluetooth/ble_drv.c:373 msgid "Can not add Characteristic." -msgstr "" +msgstr "Kann das Merkmal nicht hinzufügen." #: ports/nrf/drivers/bluetooth/ble_drv.c:400 msgid "Can not apply device name in the stack." -msgstr "" +msgstr "Der Gerätename kann nicht im Stack verwendet werden." #: ports/nrf/drivers/bluetooth/ble_drv.c:464 #: ports/nrf/drivers/bluetooth/ble_drv.c:514 msgid "Can not encode UUID, to check length." -msgstr "" +msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." #: ports/nrf/drivers/bluetooth/ble_drv.c:470 #: ports/nrf/drivers/bluetooth/ble_drv.c:520 msgid "Can encode UUID into the advertisement packet." -msgstr "" +msgstr "Kann UUID in das advertisement packet kodieren." #: ports/nrf/drivers/bluetooth/ble_drv.c:545 msgid "Can not fit data into the advertisement packet." -msgstr "" +msgstr "Daten können nicht in das advertisement packet eingefügt werden." #: ports/nrf/drivers/bluetooth/ble_drv.c:558 #: ports/nrf/drivers/bluetooth/ble_drv.c:604 #, c-format msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "" +msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:614 #, c-format msgid "Can not start advertisement. status: 0x%02x" -msgstr "" +msgstr "Kann advertisement nicht starten. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:631 #, c-format msgid "Can not stop advertisement. status: 0x%02x" -msgstr "" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:650 #: ports/nrf/drivers/bluetooth/ble_drv.c:726 #, c-format msgid "Can not read attribute value. status: 0x%02x" -msgstr "" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:667 #: ports/nrf/drivers/bluetooth/ble_drv.c:756 #, c-format msgid "Can not write attribute value. status: 0x%02x" -msgstr "" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:691 #, c-format msgid "Can not notify attribute value. status: 0x%02x" -msgstr "" +msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:784 #, c-format msgid "Can not start scanning. status: 0x%02x" -msgstr "" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" #: ports/nrf/drivers/bluetooth/ble_drv.c:829 #, c-format msgid "Can not connect. status: 0x%02x" -msgstr "" +msgstr "Kann nicht verbinden. Status: 0x%02x" #: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 #: ports/nrf/modules/ubluepy/ubluepy_service.c:80 #: ports/nrf/modules/ubluepy/ubluepy_service.c:132 #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 msgid "Invalid UUID parameter" -msgstr "" +msgstr "Ungültiger UUID-Parameter" #: ports/nrf/modules/ubluepy/ubluepy_service.c:73 msgid "Invalid Service type" -msgstr "" +msgstr "Ungültiger Diensttyp" #: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 msgid "Invalid UUID string length" -msgstr "" +msgstr "Ungültige UUID-Stringlänge" #: ports/unix/modffi.c:138 msgid "Unknown type" -msgstr "" +msgstr "Unbekannter Typ" #: ports/unix/modffi.c:207 ports/unix/modffi.c:265 msgid "Error in ffi_prep_cif" -msgstr "" +msgstr "Fehler in ffi_prep_cif" #: ports/unix/modffi.c:270 msgid "ffi_prep_closure_loc" -- cgit v1.2.3 From dc82fd556bca81e6be9d5e3c5c982e2f0cd6e4c3 Mon Sep 17 00:00:00 2001 From: Bryan Siepert Date: Wed, 31 Oct 2018 01:54:09 -0700 Subject: Updating devices.h to add new devices, fix a typo and address #1239 --- ports/atmel-samd/external_flash/devices.h | 39 ++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h index 974936419..be3fa47e4 100644 --- a/ports/atmel-samd/external_flash/devices.h +++ b/ports/atmel-samd/external_flash/devices.h @@ -180,9 +180,9 @@ typedef struct { .write_status_register_split = false, \ } -// Settings for the Winbond W25Q16JV 2MiB SPI flash. +// Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) // Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf -#define W25Q16JV {\ +#define W25Q16JV_IQ {\ .total_size = (1 << 21), /* 2 MiB */ \ .start_up_time_us = 5000, \ .manufacturer_id = 0xef, \ @@ -197,6 +197,23 @@ typedef struct { .write_status_register_split = false, \ } +// Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) +// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf +#define W25Q16JV_IM {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + // Settings for the Winbond W25Q32BV 4MiB SPI flash. // Datasheet: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf #define W25Q32BV {\ @@ -213,6 +230,22 @@ typedef struct { .supports_qspi_writes = false, \ .write_status_register_split = false, \ } +// Settings for the Winbond W25Q32JV-IM 4MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf +#define W25Q32JV_IM {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} // Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) // Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf @@ -266,7 +299,7 @@ typedef struct { } -// Settings for the Winbond W25Q128JV-SQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) // Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf #define W25Q128JV_SQ {\ .total_size = (1 << 23), /* 16 MiB */ \ -- cgit v1.2.3 From 46f1a0719e5d24d0a53e64a01a667610c6c57086 Mon Sep 17 00:00:00 2001 From: caternuson Date: Wed, 31 Oct 2018 18:08:10 -0700 Subject: add channels and bits_per_sample to audioio.WaveFile --- shared-bindings/audioio/WaveFile.c | 39 ++++++++++++++++++++++++++++++++++++++ shared-bindings/audioio/WaveFile.h | 2 ++ shared-module/audioio/WaveFile.c | 8 ++++++++ 3 files changed, 49 insertions(+) diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audioio/WaveFile.c index 4ff0abdda..a3fc8017b 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audioio/WaveFile.c @@ -138,6 +138,43 @@ const mp_obj_property_t audioio_wavefile_sample_rate_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: bits_per_sample +//| +//| Bits per sample. (read only) +//| +STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample); + +const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_wavefile_get_bits_per_sample_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: channels +//| +//| Number of audio channels. (read only) +//| +STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count); + +const mp_obj_property_t audioio_wavefile_channel_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_wavefile_get_channel_count_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_wavefile_deinit_obj) }, @@ -146,6 +183,8 @@ STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_wavefile_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audioio_wavefile_bits_per_sample_obj) }, + { MP_ROM_QSTR(MP_QSTR_channels), MP_ROM_PTR(&audioio_wavefile_channel_count_obj) }, }; STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table); diff --git a/shared-bindings/audioio/WaveFile.h b/shared-bindings/audioio/WaveFile.h index 255ffbcd5..62a4200dc 100644 --- a/shared-bindings/audioio/WaveFile.h +++ b/shared-bindings/audioio/WaveFile.h @@ -40,5 +40,7 @@ void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self); bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self); uint32_t common_hal_audioio_wavefile_get_sample_rate(audioio_wavefile_obj_t* self); void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t* self, uint32_t sample_rate); +uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t* self); +uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t* self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H diff --git a/shared-module/audioio/WaveFile.c b/shared-module/audioio/WaveFile.c index e5a7b1a3b..d5dd9419c 100644 --- a/shared-module/audioio/WaveFile.c +++ b/shared-module/audioio/WaveFile.c @@ -141,6 +141,14 @@ void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t* self, self->sample_rate = sample_rate; } +uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t* self) { + return self->bits_per_sample; +} + +uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t* self) { + return self->channel_count; +} + bool audioio_wavefile_samples_signed(audioio_wavefile_obj_t* self) { return self->bits_per_sample > 8; } -- cgit v1.2.3 From e203ce9ce542b58ee4b6b7ffc844a67d78aa09cd Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 31 Oct 2018 23:18:59 -0400 Subject: Use adafruit/nrfx fork of NordicSemiconductor/nrfx --- .gitmodules | 2 +- ports/nrf/nrfx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index c0a3446b9..38b6ea5df 100644 --- a/.gitmodules +++ b/.gitmodules @@ -75,7 +75,7 @@ url = https://github.com/adafruit/Adafruit_CircuitPython_Crickit [submodule "ports/nrf/nrfx"] path = ports/nrf/nrfx - url = https://github.com/NordicSemiconductor/nrfx.git + url = https://github.com/adafruit/nrfx.git [submodule "lib/tinyusb"] path = lib/tinyusb url = https://github.com/hathach/tinyusb.git diff --git a/ports/nrf/nrfx b/ports/nrf/nrfx index d4ebe15f5..b96950abf 160000 --- a/ports/nrf/nrfx +++ b/ports/nrf/nrfx @@ -1 +1 @@ -Subproject commit d4ebe15f58de1442e3eed93b40d13930e7785903 +Subproject commit b96950abf27229c2a3b1719d60691321246bfc94 -- cgit v1.2.3 From 844b674a1e2aefd569adf5832eb6f81de53941c1 Mon Sep 17 00:00:00 2001 From: Bryan Siepert Date: Thu, 1 Nov 2018 09:42:48 -0700 Subject: adding support for the CP32-M4 --- ports/atmel-samd/boards/cp32-m4/board.c | 39 ++++++++++++++++++++++ ports/atmel-samd/boards/cp32-m4/mpconfigboard.h | 39 ++++++++++++++++++++++ ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk | 10 ++++++ ports/atmel-samd/boards/cp32-m4/pins.c | 41 ++++++++++++++++++++++++ ports/atmel-samd/external_flash/devices.h | 18 ++++++++++- 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 ports/atmel-samd/boards/cp32-m4/board.c create mode 100644 ports/atmel-samd/boards/cp32-m4/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/cp32-m4/pins.c diff --git a/ports/atmel-samd/boards/cp32-m4/board.c b/ports/atmel-samd/boards/cp32-m4/board.c new file mode 100644 index 000000000..0f60736a2 --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h new file mode 100644 index 000000000..bcad7f18b --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "CP32-M4" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define MICROPY_HW_APA102_MOSI (&pin_PA17) +#define MICROPY_HW_APA102_SCK (&pin_PA16) + + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11| PORT_PA16| PORT_PA17) +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#include "external_flash/devices.h" + +// these are the labeled pins (SDA, SCL, SCK, MOSI, MISO, etc) +#define EXTERNAL_FLASH_DEVICE_COUNT 1 +#define EXTERNAL_FLASH_DEVICES W25Q128JV_PM + +#include "external_flash/external_flash.h" + +#define DEFAULT_I2C_BUS_SCL (&pin_PB09) +#define DEFAULT_I2C_BUS_SDA (&pin_PB08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA22) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA23) +#define DEFAULT_SPI_BUS_MISO (&pin_PA21) + +#define DEFAULT_UART_BUS_RX (&pin_PA12) +#define DEFAULT_UART_BUS_TX (&pin_PA13) diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk new file mode 100644 index 000000000..56fc9b2fb --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk @@ -0,0 +1,10 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8021 +USB_PRODUCT = "CP32-M4" +USB_MANUFACTURER = "Nadda-Reel Company LLC" + +QSPI_FLASH_FILESYSTEM = 1 + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/cp32-m4/pins.c b/ports/atmel-samd/boards/cp32-m4/pins.c new file mode 100644 index 000000000..93c169c8b --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_P), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW3_4), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW1_2), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_N), MP_ROM_PTR(&pin_PA05) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SW9), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW7), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BACKLIGHT_PWM), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR3), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW5), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR4), MP_ROM_PTR(&pin_PA15) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW6), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_CS0), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_MISO), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_SCK), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_MOSI), MP_ROM_PTR(&pin_PA23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_CS1), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR5), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_SW8), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SW10), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h index be3fa47e4..58da2e509 100644 --- a/ports/atmel-samd/external_flash/devices.h +++ b/ports/atmel-samd/external_flash/devices.h @@ -302,7 +302,7 @@ typedef struct { // Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) // Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf #define W25Q128JV_SQ {\ - .total_size = (1 << 23), /* 16 MiB */ \ + .total_size = (1 << 24), /* 16 MiB */ \ .start_up_time_us = 5000, \ .manufacturer_id = 0xef, \ .memory_type = 0x40, \ @@ -317,5 +317,21 @@ typedef struct { } +// Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_PM {\ + .total_size = (1 << 24), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} #endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H -- cgit v1.2.3 From 4dfba2f8acec7d76fa61c13fcec662b6d957f69a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 1 Nov 2018 17:14:11 -0400 Subject: put .frozen before /lib in sys.path; update frozen libraries --- frozen/Adafruit_CircuitPython_BusDevice | 2 +- frozen/Adafruit_CircuitPython_CircuitPlayground | 2 +- frozen/Adafruit_CircuitPython_Crickit | 2 +- frozen/Adafruit_CircuitPython_DotStar | 2 +- frozen/Adafruit_CircuitPython_HID | 2 +- frozen/Adafruit_CircuitPython_IRRemote | 2 +- frozen/Adafruit_CircuitPython_LIS3DH | 2 +- frozen/Adafruit_CircuitPython_Motor | 2 +- frozen/Adafruit_CircuitPython_NeoPixel | 2 +- frozen/Adafruit_CircuitPython_Thermistor | 2 +- frozen/Adafruit_CircuitPython_seesaw | 2 +- main.c | 3 ++- ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk | 2 ++ ports/esp8266/main.c | 3 ++- tools/preprocess_frozen_modules.py | 2 +- 15 files changed, 18 insertions(+), 14 deletions(-) diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index 079196414..d86fc7e81 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit 07919641470edb602585c6a91f7b8eacf17e664b +Subproject commit d86fc7e81d51465ca1eae6f8c1141f81f065f5aa diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index d0aa6dc56..f4ee725fb 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit d0aa6dc56d66decfae92daced7384c1e3518a666 +Subproject commit f4ee725fb93fd1a31666d3f71d10c94eb96df7c8 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 44f52c5da..412392c8b 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 44f52c5dacd9fc605565e5794e95c9a785aaf693 +Subproject commit 412392c8bdb6b4378e007eb7974c76b92fa9ff1d diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index af25424ee..03c24157d 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit af25424ee7dbebea3e5d77390c017018ffa52d36 +Subproject commit 03c24157d46672c723021686f7a838cfeb2db2ba diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index 5c2f6ef1e..f5e70e092 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit 5c2f6ef1ed80f24b6a3878067d40350d3725e198 +Subproject commit f5e70e09250f2a25ebb6487a30a763041644c5d3 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index c29e10b59..ec11164ec 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit c29e10b590efbdf06163897b49cd0c2bea82ad6e +Subproject commit ec11164ec6682094a48d0f9848d2c4c89c08f3bc diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index c4152a0d8..6298cd363 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit c4152a0d87a04903ae0e612eb381af440c9e28b3 +Subproject commit 6298cd363811ad6ac10d4325c898be87a70d7bb2 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index e0b709f17..4421e7966 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit e0b709f1710555da67705360870ba0d14ced7e06 +Subproject commit 4421e79661002ff8da6c0c4f22940ec843ee300b diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index e9f50cb66..72e8f3855 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit e9f50cb6678a1684591ee021b95a3c4b51786fee +Subproject commit 72e8f3855ecd136641d536a49311c38ee4f76f33 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 00f4ebca6..eae584918 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 00f4ebca6c740b76c1c464f83d514ac20b0600e1 +Subproject commit eae584918e72ff5fa323825470f276b31829ef9f diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 340cd17fa..e3e3021d8 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 340cd17fad0c29d3a70d6e298a30ecc753df054e +Subproject commit e3e3021d8578fde450511b47a085d9d56ab46741 diff --git a/main.c b/main.c index cbc0b093c..2484d3f1f 100644 --- a/main.c +++ b/main.c @@ -92,9 +92,10 @@ void reset_mp(void) { mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); // Frozen modules are in their own pseudo-dir, e.g., ".frozen". + // Prioritize .frozen over /lib. mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); } diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk index 0f8d0f9ca..ddc262a57 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk @@ -10,6 +10,8 @@ LONGINT_IMPL = NONE CHIP_VARIANT = SAMD21E18A CHIP_FAMILY = samd21 +CFLAGS_INLINE_LIMIT = 45 + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index c590ab59e..dda17bb37 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -95,10 +95,11 @@ STATIC void mp_reset(void) { mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); // Frozen modules are in their own pseudo-dir, e.g., ".frozen". + // Prioritize .frozen over /lib. mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py index d157deeee..f2b59ffc0 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -33,7 +33,7 @@ def copy_and_process(in_dir, out_dir): for root, subdirs, files in os.walk(in_dir): # Skip library examples directories. - if Path(root).name in ['examples', 'docs']: + if Path(root).name in ['examples', 'tests', 'docs']: continue for file in files: -- cgit v1.2.3 From 4f2f571536727aea7cf8cee68bfd27ed834ede49 Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Sat, 3 Nov 2018 14:01:30 -0400 Subject: Adding the serial_bytes_available() method to the 3.x branch --- ports/atmel-samd/common-hal/supervisor/Runtime.c | 4 ++++ ports/nrf/common-hal/supervisor/Runtime.c | 4 ++++ shared-bindings/supervisor/Runtime.c | 26 ++++++++++++++++++++++++ shared-bindings/supervisor/Runtime.h | 2 ++ 4 files changed, 36 insertions(+) diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c index 8efe7cb78..2636fe646 100755 --- a/ports/atmel-samd/common-hal/supervisor/Runtime.c +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -32,3 +32,7 @@ bool common_hal_get_serial_connected(void) { return (bool) usb_connected(); } +bool common_hal_get_serial_bytes_available(void) { + return (bool) usb_bytes_available(); +} + diff --git a/ports/nrf/common-hal/supervisor/Runtime.c b/ports/nrf/common-hal/supervisor/Runtime.c index b73a94a1b..feab6987d 100755 --- a/ports/nrf/common-hal/supervisor/Runtime.c +++ b/ports/nrf/common-hal/supervisor/Runtime.c @@ -32,3 +32,7 @@ bool common_hal_get_serial_connected(void) { return (bool) serial_connected(); } +bool common_hal_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); +} + diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index b061595cf..27b62abd4 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -53,6 +53,12 @@ //| //| Returns the USB serial communication status (read-only). //| +//| .. attribute:: runtime.serial_bytes_available +//| +//| Returns the whether any bytes are available to read +//| on the USB serial input. Allows for polling to see whether +//| to call the built-in input() or wait. (read-only) +//| //| .. note:: //| //| SAMD: Will return ``True`` if the USB serial connection @@ -80,8 +86,28 @@ const mp_obj_property_t supervisor_serial_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; +/*Added to allow for polling of USB Console*/ +STATIC mp_obj_t supervisor_get_serial_bytes_available(mp_obj_t self){ + if (!common_hal_get_serial_bytes_available()) { + return mp_const_false; + } + else { + return mp_const_true; + } +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_bytes_available_obj, supervisor_get_serial_bytes_available); + +const mp_obj_property_t supervisor_serial_bytes_available_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&supervisor_get_serial_bytes_available_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_serial_bytes_available_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index 4a67925ec..864b070cd 100755 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -35,6 +35,8 @@ const mp_obj_type_t supervisor_runtime_type; bool common_hal_get_serial_connected(void); +bool common_hal_get_serial_bytes_available(void); + //TODO: placeholders for future functions //bool common_hal_get_repl_active(void); //bool common_hal_get_usb_enumerated(void); -- cgit v1.2.3 From bd4188a0924700d30d53a860c56e4bd4c081608b Mon Sep 17 00:00:00 2001 From: ATMakersBill Date: Sat, 3 Nov 2018 14:42:27 -0400 Subject: adding changes to mpconfigboard.mk to reduce memory usage on CPX per @danh --- ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk index 831106adc..aff875e29 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -17,3 +17,6 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor + +#Adding per @danh to reduce memory usage and get the latest changes in +CFLAGS_INLINE_LIMIT = 55 -- cgit v1.2.3 From a15ed0b9127b8ed7f245501101db76201cdb6008 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 4 Nov 2018 00:07:42 -0400 Subject: Fix Trellis M4 DotStar pin assignments. --- ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h | 13 +++++++------ ports/atmel-samd/boards/trellis_m4_express/pins.c | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h index 05f2be0bc..1464d100c 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -1,19 +1,20 @@ + #define MICROPY_HW_BOARD_NAME "Adafruit Trellis M4 Express" #define MICROPY_HW_MCU_NAME "samd51g19" #define CIRCUITPY_MCU_FAMILY samd51 // This is for Rev D -#define MICROPY_HW_APA102_MOSI (&pin_PA01) -#define MICROPY_HW_APA102_SCK (&pin_PA00) +#define MICROPY_HW_APA102_MOSI (&pin_PB03) +#define MICROPY_HW_APA102_SCK (&pin_PB02) #define CIRCUITPY_BITBANG_APA102 // These are pins not to reset. -// QSPI Data pins & DotStar pins -#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) -// QSPI CS, and QSPI SCK -#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar Pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB02 | PORT_PB03 | PORT_PB10 | PORT_PB11) #define MICROPY_PORT_C (0) #define MICROPY_PORT_D (0) diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c index 44ffc6eaf..9626f525f 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/pins.c +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -39,8 +39,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { // NeoPixels { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA01) }, - { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; -- cgit v1.2.3 From 85fbdefe774d03b6ade737b5ff38cfd30b60cdd6 Mon Sep 17 00:00:00 2001 From: caternuson Date: Mon, 5 Nov 2018 08:05:43 -0800 Subject: change channels to channel_count --- shared-bindings/audioio/WaveFile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audioio/WaveFile.c index a3fc8017b..7c5a6d5dc 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audioio/WaveFile.c @@ -184,7 +184,7 @@ STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_wavefile_sample_rate_obj) }, { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audioio_wavefile_bits_per_sample_obj) }, - { MP_ROM_QSTR(MP_QSTR_channels), MP_ROM_PTR(&audioio_wavefile_channel_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audioio_wavefile_channel_count_obj) }, }; STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table); -- cgit v1.2.3 From 55cbeb6fc67e2caaf4f874eff3b85839676253c0 Mon Sep 17 00:00:00 2001 From: caternuson Date: Mon, 5 Nov 2018 14:49:24 -0800 Subject: in doc string as well --- shared-bindings/audioio/WaveFile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audioio/WaveFile.c index 7c5a6d5dc..2d2ef578b 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audioio/WaveFile.c @@ -156,7 +156,7 @@ const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. attribute:: channels +//| .. attribute:: channel_count //| //| Number of audio channels. (read only) //| -- cgit v1.2.3 From 9d91111b1b6a1eee77a88b13faf695ee0c5caea3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 19 Oct 2018 18:46:22 -0700 Subject: Move atmel-samd to tinyusb and support nRF flash. This started while adding USB MIDI support (and descriptor support is in this change.) When seeing that I'd have to implement the MIDI class logic twice, once for atmel-samd and once for nrf, I decided to refactor the USB stack so its shared across ports. This has led to a number of changes that remove items from the ports folder and move them into supervisor. Furthermore, we had external SPI flash support for nrf pending so I factored out the connection between the usb stack and the flash API as well. This PR also includes the QSPI support for nRF. --- .gitmodules | 2 +- lib/tinyusb | 2 +- main.c | 3 + ports/atmel-samd/Makefile | 72 +-- ports/atmel-samd/background.c | 7 +- ports/atmel-samd/boards/arduino_zero/board.c | 7 - .../atmel-samd/boards/arduino_zero/mpconfigboard.h | 8 +- .../circuitplayground_express/mpconfigboard.h | 39 +- .../circuitplayground_express/mpconfigboard.mk | 2 + .../mpconfigboard.h | 40 +- .../mpconfigboard.mk | 2 + .../boards/feather_m0_adalogger/mpconfigboard.h | 4 +- .../boards/feather_m0_basic/mpconfigboard.h | 4 +- .../boards/feather_m0_express/mpconfigboard.h | 37 +- .../boards/feather_m0_express/mpconfigboard.mk | 2 + .../feather_m0_express_crickit/mpconfigboard.h | 38 +- .../feather_m0_express_crickit/mpconfigboard.mk | 2 + .../boards/feather_m0_rfm69/mpconfigboard.h | 4 +- .../boards/feather_m0_rfm9x/mpconfigboard.h | 4 +- .../boards/feather_m0_supersized/mpconfigboard.h | 37 +- .../boards/feather_m0_supersized/mpconfigboard.mk | 2 + .../boards/feather_m4_express/mpconfigboard.h | 7 - .../boards/feather_m4_express/mpconfigboard.mk | 3 + .../feather_radiofruit_zigbee/mpconfigboard.h | 38 +- .../feather_radiofruit_zigbee/mpconfigboard.mk | 2 + ports/atmel-samd/boards/gemma_m0/mpconfigboard.h | 2 - .../boards/grandcentral_m4_express/board.c | 7 - .../boards/grandcentral_m4_express/mpconfigboard.h | 11 +- .../grandcentral_m4_express/mpconfigboard.mk | 3 + .../boards/hallowing_m0_express/mpconfigboard.h | 41 +- .../boards/hallowing_m0_express/mpconfigboard.mk | 2 + .../boards/itsybitsy_m0_express/mpconfigboard.h | 38 +- .../boards/itsybitsy_m0_express/mpconfigboard.mk | 2 + .../boards/itsybitsy_m4_express/mpconfigboard.h | 7 - .../boards/itsybitsy_m4_express/mpconfigboard.mk | 2 + ports/atmel-samd/boards/meowmeow/mpconfigboard.h | 6 +- .../boards/metro_m0_express/mpconfigboard.h | 39 +- .../boards/metro_m0_express/mpconfigboard.mk | 4 + ports/atmel-samd/boards/metro_m4_express/board.c | 7 - .../boards/metro_m4_express/mpconfigboard.h | 19 +- .../boards/metro_m4_express/mpconfigboard.mk | 3 + ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h | 2 - .../boards/trellis_m4_express/mpconfigboard.h | 7 - .../boards/trellis_m4_express/mpconfigboard.mk | 2 + ports/atmel-samd/boards/trinket_m0/mpconfigboard.h | 2 - .../boards/trinket_m0_haxpress/mpconfigboard.h | 42 +- .../boards/trinket_m0_haxpress/mpconfigboard.mk | 2 + ports/atmel-samd/boards/ugame10/mpconfigboard.h | 39 +- ports/atmel-samd/boards/ugame10/mpconfigboard.mk | 2 + ports/atmel-samd/common-hal/busio/SPI.c | 47 ++ ports/atmel-samd/common-hal/busio/SPI.h | 3 + ports/atmel-samd/common-hal/microcontroller/Pin.c | 15 +- ports/atmel-samd/common-hal/microcontroller/Pin.h | 1 + .../common-hal/microcontroller/__init__.c | 220 +++++-- ports/atmel-samd/common-hal/storage/__init__.c | 58 -- ports/atmel-samd/common-hal/supervisor/Runtime.c | 7 +- ports/atmel-samd/common-hal/usb_hid/Device.c | 106 ---- ports/atmel-samd/common-hal/usb_hid/Device.h | 53 -- ports/atmel-samd/common-hal/usb_hid/__init__.c | 152 ----- ports/atmel-samd/external_flash/common_commands.h | 46 -- ports/atmel-samd/external_flash/devices.h | 337 ---------- ports/atmel-samd/external_flash/external_flash.c | 699 --------------------- ports/atmel-samd/external_flash/external_flash.h | 64 -- ports/atmel-samd/external_flash/qspi_flash.c | 242 ------- ports/atmel-samd/external_flash/spi_flash.c | 158 ----- ports/atmel-samd/external_flash/spi_flash_api.h | 45 -- ports/atmel-samd/flash_api.c | 51 -- ports/atmel-samd/flash_api.h | 36 -- ports/atmel-samd/internal_flash.c | 285 --------- ports/atmel-samd/internal_flash.h | 69 -- ports/atmel-samd/mpconfigport.h | 10 +- ports/atmel-samd/mpconfigport.mk | 2 +- ports/atmel-samd/mphalport.c | 34 - ports/atmel-samd/mphalport.h | 2 - ports/atmel-samd/peripherals | 2 +- ports/atmel-samd/reset.c | 4 - ports/atmel-samd/supervisor/filesystem.c | 101 --- ports/atmel-samd/supervisor/internal_flash.c | 209 ++++++ ports/atmel-samd/supervisor/internal_flash.h | 69 ++ .../supervisor/internal_flash_root_pointers.h | 31 + ports/atmel-samd/supervisor/port.c | 39 +- ports/atmel-samd/supervisor/qspi_flash.c | 232 +++++++ ports/atmel-samd/supervisor/serial.c | 79 --- ports/atmel-samd/supervisor/usb.c | 59 ++ ports/atmel-samd/tick.h | 2 +- ports/atmel-samd/tools/gen_usb_descriptor.py | 353 ----------- ports/atmel-samd/tools/hid_report_descriptors.py | 239 ------- ports/atmel-samd/usb.c | 326 ---------- ports/atmel-samd/usb.h | 42 -- ports/atmel-samd/usb_mass_storage.c | 338 ---------- ports/atmel-samd/usb_mass_storage.h | 48 -- ports/esp8266/Makefile | 2 - ports/esp8266/mpconfigport.h | 2 - ports/nrf/Makefile | 48 +- ports/nrf/README.md | 2 +- ports/nrf/background.c | 11 +- ports/nrf/board_busses.c | 2 +- ports/nrf/boards/feather_nrf52840_express/board.c | 2 - .../feather_nrf52840_express/mpconfigboard.h | 23 +- .../feather_nrf52840_express/mpconfigboard.mk | 9 + ports/nrf/boards/makerdiary_nrf52840_mdk/board.c | 2 - .../boards/makerdiary_nrf52840_mdk/mpconfigboard.h | 25 +- .../makerdiary_nrf52840_mdk/mpconfigboard.mk | 9 + ports/nrf/boards/pca10056/board.c | 2 - ports/nrf/boards/pca10056/mpconfigboard.h | 23 + ports/nrf/boards/pca10056/mpconfigboard.mk | 9 + ports/nrf/boards/pca10059/board.c | 5 - ports/nrf/boards/pca10059/mpconfigboard.mk | 5 + ports/nrf/common-hal/busio/SPI.c | 18 + ports/nrf/common-hal/busio/UART.c | 2 +- ports/nrf/common-hal/digitalio/DigitalInOut.c | 5 + ports/nrf/common-hal/microcontroller/Pin.c | 13 +- ports/nrf/common-hal/microcontroller/Pin.h | 1 + ports/nrf/common-hal/microcontroller/Processor.c | 7 +- ports/nrf/common-hal/pulseio/PulseIn.c | 2 +- ports/nrf/common-hal/pulseio/PulseOut.c | 2 +- ports/nrf/common-hal/storage/__init__.c | 47 -- ports/nrf/common-hal/usb_hid/Device.c | 88 --- ports/nrf/common-hal/usb_hid/Device.h | 94 --- ports/nrf/common-hal/usb_hid/__init__.c | 160 ----- ports/nrf/internal_flash.c | 226 ------- ports/nrf/internal_flash.h | 59 -- ports/nrf/mpconfigport.h | 5 +- ports/nrf/mpconfigport.mk | 1 + ports/nrf/mphalport.c | 81 --- ports/nrf/nrfx_config.h | 3 + ports/nrf/peripherals/nrf/timers.c | 2 +- ports/nrf/supervisor/filesystem.c | 97 --- ports/nrf/supervisor/internal_flash.c | 121 ++++ ports/nrf/supervisor/internal_flash.h | 42 ++ .../nrf/supervisor/internal_flash_root_pointers.h | 31 + ports/nrf/supervisor/port.c | 7 + ports/nrf/supervisor/qspi_flash.c | 146 +++++ ports/nrf/supervisor/serial.c | 48 +- ports/nrf/supervisor/usb.c | 83 +++ ports/nrf/tick.h | 2 +- ports/nrf/usb/tusb_config.h | 129 ---- ports/nrf/usb/usb.c | 169 ----- ports/nrf/usb/usb.h | 34 - ports/nrf/usb/usb_desc.c | 393 ------------ ports/nrf/usb/usb_desc.h | 87 --- ports/nrf/usb/usb_msc_flash.c | 143 ----- shared-bindings/busio/SPI.h | 3 + shared-bindings/usb_hid/Device.h | 2 +- shared-module/bitbangio/SPI.c | 3 +- shared-module/storage/__init__.c | 26 + shared-module/usb_hid/Device.c | 88 +++ shared-module/usb_hid/Device.h | 55 ++ shared-module/usb_hid/__init__.c | 154 +++++ supervisor/flash.h | 54 ++ supervisor/flash_root_pointers.h | 35 ++ supervisor/port.h | 3 + supervisor/serial.h | 10 + supervisor/shared/external_flash/common_commands.h | 47 ++ supervisor/shared/external_flash/devices.h | 375 +++++++++++ supervisor/shared/external_flash/external_flash.c | 615 ++++++++++++++++++ supervisor/shared/external_flash/external_flash.h | 48 ++ .../external_flash/external_flash_root_pointers.h | 35 ++ supervisor/shared/external_flash/qspi_flash.c | 56 ++ supervisor/shared/external_flash/qspi_flash.h | 31 + supervisor/shared/external_flash/spi_flash.c | 150 +++++ supervisor/shared/filesystem.c | 109 ++++ supervisor/shared/flash.c | 123 ++++ supervisor/shared/micropython.c | 58 ++ supervisor/shared/rgb_led_status.h | 2 +- supervisor/shared/serial.c | 56 ++ supervisor/shared/status_leds.c | 62 ++ supervisor/shared/status_leds.h | 36 ++ supervisor/shared/usb/tusb_config.h | 115 ++++ supervisor/shared/usb/usb.c | 140 +++++ supervisor/shared/usb/usb_desc.c | 46 ++ supervisor/shared/usb/usb_desc.h | 43 ++ supervisor/shared/usb/usb_msc_flash.c | 205 ++++++ supervisor/spi_flash_api.h | 45 ++ supervisor/supervisor.mk | 68 +- supervisor/usb.h | 44 ++ tools/gen_usb_descriptor.py | 474 ++++++++++++++ tools/hid_report_descriptors.py | 239 +++++++ tools/usb_descriptor | 2 +- 179 files changed, 5248 insertions(+), 6512 deletions(-) delete mode 100644 ports/atmel-samd/common-hal/storage/__init__.c delete mode 100644 ports/atmel-samd/common-hal/usb_hid/Device.c delete mode 100644 ports/atmel-samd/common-hal/usb_hid/Device.h delete mode 100644 ports/atmel-samd/common-hal/usb_hid/__init__.c delete mode 100644 ports/atmel-samd/external_flash/common_commands.h delete mode 100644 ports/atmel-samd/external_flash/devices.h delete mode 100644 ports/atmel-samd/external_flash/external_flash.c delete mode 100644 ports/atmel-samd/external_flash/external_flash.h delete mode 100644 ports/atmel-samd/external_flash/qspi_flash.c delete mode 100644 ports/atmel-samd/external_flash/spi_flash.c delete mode 100644 ports/atmel-samd/external_flash/spi_flash_api.h delete mode 100644 ports/atmel-samd/flash_api.c delete mode 100644 ports/atmel-samd/flash_api.h delete mode 100644 ports/atmel-samd/internal_flash.c delete mode 100644 ports/atmel-samd/internal_flash.h delete mode 100644 ports/atmel-samd/supervisor/filesystem.c create mode 100644 ports/atmel-samd/supervisor/internal_flash.c create mode 100644 ports/atmel-samd/supervisor/internal_flash.h create mode 100644 ports/atmel-samd/supervisor/internal_flash_root_pointers.h create mode 100644 ports/atmel-samd/supervisor/qspi_flash.c delete mode 100644 ports/atmel-samd/supervisor/serial.c create mode 100644 ports/atmel-samd/supervisor/usb.c delete mode 100644 ports/atmel-samd/tools/gen_usb_descriptor.py delete mode 100644 ports/atmel-samd/tools/hid_report_descriptors.py delete mode 100644 ports/atmel-samd/usb.c delete mode 100644 ports/atmel-samd/usb.h delete mode 100644 ports/atmel-samd/usb_mass_storage.c delete mode 100644 ports/atmel-samd/usb_mass_storage.h delete mode 100644 ports/nrf/common-hal/storage/__init__.c delete mode 100644 ports/nrf/common-hal/usb_hid/Device.c delete mode 100644 ports/nrf/common-hal/usb_hid/Device.h delete mode 100644 ports/nrf/common-hal/usb_hid/__init__.c delete mode 100644 ports/nrf/internal_flash.c delete mode 100644 ports/nrf/internal_flash.h delete mode 100644 ports/nrf/supervisor/filesystem.c create mode 100644 ports/nrf/supervisor/internal_flash.c create mode 100644 ports/nrf/supervisor/internal_flash.h create mode 100644 ports/nrf/supervisor/internal_flash_root_pointers.h create mode 100644 ports/nrf/supervisor/qspi_flash.c create mode 100644 ports/nrf/supervisor/usb.c delete mode 100644 ports/nrf/usb/tusb_config.h delete mode 100644 ports/nrf/usb/usb.c delete mode 100644 ports/nrf/usb/usb.h delete mode 100644 ports/nrf/usb/usb_desc.c delete mode 100644 ports/nrf/usb/usb_desc.h delete mode 100644 ports/nrf/usb/usb_msc_flash.c create mode 100644 shared-module/usb_hid/Device.c create mode 100644 shared-module/usb_hid/Device.h create mode 100644 shared-module/usb_hid/__init__.c create mode 100644 supervisor/flash.h create mode 100644 supervisor/flash_root_pointers.h create mode 100644 supervisor/shared/external_flash/common_commands.h create mode 100644 supervisor/shared/external_flash/devices.h create mode 100644 supervisor/shared/external_flash/external_flash.c create mode 100644 supervisor/shared/external_flash/external_flash.h create mode 100644 supervisor/shared/external_flash/external_flash_root_pointers.h create mode 100644 supervisor/shared/external_flash/qspi_flash.c create mode 100644 supervisor/shared/external_flash/qspi_flash.h create mode 100644 supervisor/shared/external_flash/spi_flash.c create mode 100644 supervisor/shared/filesystem.c create mode 100644 supervisor/shared/flash.c create mode 100644 supervisor/shared/micropython.c create mode 100644 supervisor/shared/serial.c create mode 100644 supervisor/shared/status_leds.c create mode 100644 supervisor/shared/status_leds.h create mode 100644 supervisor/shared/usb/tusb_config.h create mode 100644 supervisor/shared/usb/usb.c create mode 100644 supervisor/shared/usb/usb_desc.c create mode 100644 supervisor/shared/usb/usb_desc.h create mode 100644 supervisor/shared/usb/usb_msc_flash.c create mode 100644 supervisor/spi_flash_api.h create mode 100644 supervisor/usb.h create mode 100644 tools/gen_usb_descriptor.py create mode 100644 tools/hid_report_descriptors.py diff --git a/.gitmodules b/.gitmodules index 38b6ea5df..1c1f8eb65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -78,7 +78,7 @@ url = https://github.com/adafruit/nrfx.git [submodule "lib/tinyusb"] path = lib/tinyusb - url = https://github.com/hathach/tinyusb.git + url = https://github.com/tannewt/tinyusb.git branch = develop [submodule "tools/huffman"] path = tools/huffman diff --git a/lib/tinyusb b/lib/tinyusb index 33c61bfda..30e3c6413 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 33c61bfda2c3aada3cb06d36e12d7cf57da02037 +Subproject commit 30e3c64134789416e10ed867fa12c210b808e98f diff --git a/main.c b/main.c index c1379c571..ac55b72ba 100755 --- a/main.c +++ b/main.c @@ -51,6 +51,7 @@ #include "supervisor/shared/autoreload.h" #include "supervisor/shared/translate.h" #include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/status_leds.h" #include "supervisor/shared/stack.h" #include "supervisor/serial.h" @@ -388,6 +389,8 @@ int __attribute__((used)) main(void) { // initialise the cpu and peripherals safe_mode_t safe_mode = port_init(); + // Turn on LEDs + init_status_leds(); rgb_led_status_init(); stack_init(); diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 7861f4235..552be92be 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -45,16 +45,13 @@ INC += -I. \ -Iasf4/$(CHIP_FAMILY)/hpl/tc \ -Iasf4/$(CHIP_FAMILY)/include \ -Iasf4/$(CHIP_FAMILY)/CMSIS/Include \ - -Iasf4/$(CHIP_FAMILY)/usb \ - -Iasf4/$(CHIP_FAMILY)/usb/class/cdc \ - -Iasf4/$(CHIP_FAMILY)/usb/class/hid \ - -Iasf4/$(CHIP_FAMILY)/usb/class/msc \ - -Iasf4/$(CHIP_FAMILY)/usb/device \ -Iasf4_conf/$(CHIP_FAMILY) \ -Iboards/$(BOARD) \ -Iboards/ \ -Iperipherals/ \ -Ifreetouch \ + -I../../lib/tinyusb/src \ + -I../../supervisor/shared/usb \ -I$(BUILD) BASE_CFLAGS = \ @@ -90,11 +87,15 @@ BASE_CFLAGS = \ # NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. ifeq ($(CHIP_FAMILY), samd21) -CFLAGS = -Os -DNDEBUG +CFLAGS += -Os -DNDEBUG +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 endif ifeq ($(CHIP_FAMILY), samd51) -CFLAGS = -Os -DNDEBUG +CFLAGS += -O0 -DNDEBUG +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 endif #Debugging/Optimization @@ -104,7 +105,7 @@ ifeq ($(DEBUG), 1) # You may want to disable -flto if it interferes with debugging. CFLAGS += -flto # You may want to enable these flags to make setting breakpoints easier. -## CFLAGS += -fno-inline -fno-ipa-sra + # CFLAGS += -fno-inline -fno-ipa-sra ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -DENABLE_MICRO_TRACE_BUFFER endif @@ -204,7 +205,6 @@ SRC_ASF := \ hal/src/hal_spi_m_sync.c \ hal/src/hal_timer.c \ hal/src/hal_usart_async.c \ - hal/src/hal_usb_device.c \ hpl/adc/hpl_adc.c \ hpl/core/hpl_init.c \ hpl/dac/hpl_dac.c \ @@ -214,12 +214,6 @@ SRC_ASF := \ hpl/rtc/hpl_rtc.c \ hpl/sercom/hpl_sercom.c \ hpl/systick/hpl_systick.c \ - hpl/usb/hpl_usb.c \ - usb/class/cdc/device/cdcdf_acm.c \ - usb/class/hid/device/hiddf_generic.c \ - usb/class/msc/device/mscdf.c \ - usb/device/usbdc.c \ - usb/usb_protocol.c \ hal/utils/src/utils_list.c \ hal/utils/src/utils_ringbuffer.c \ @@ -246,7 +240,6 @@ SRC_C = \ board_busses.c \ background.c \ fatfs_port.c \ - flash_api.c \ mphalport.c \ reset.c \ peripherals/samd/clocks.c \ @@ -265,8 +258,6 @@ SRC_C = \ peripherals/samd/$(CHIP_FAMILY)/sercom.c \ peripherals/samd/$(CHIP_FAMILY)/timers.c \ tick.c \ - usb.c \ - usb_mass_storage.c \ bindings/samd/__init__.c \ bindings/samd/Clock.c \ boards/$(BOARD)/board.c \ @@ -274,6 +265,8 @@ SRC_C = \ lib/oofatfs/ff.c \ lib/oofatfs/option/ccsbcs.c \ lib/timeutils/timeutils.c \ + lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd.c \ + lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal.c \ lib/utils/buffer_helper.c \ lib/utils/context_manager_helpers.c \ lib/utils/interrupt_char.c \ @@ -282,7 +275,6 @@ SRC_C = \ lib/utils/sys_stdio_mphal.c \ lib/libc/string0.c \ lib/mp-readline/readline.c \ - $(BUILD)/autogen_usb_descriptor.c \ freetouch/adafruit_ptc.c \ supervisor/shared/memory.c @@ -306,19 +298,6 @@ SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ endif # MICROPY_PY_WIZNET5K endif # MICROPY_PY_NETWORK -# Choose which flash filesystem impl to use. -# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive. -# But that might not be true in the future.) -ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) -SRC_C += internal_flash.c -endif -ifeq ($(SPI_FLASH_FILESYSTEM),1) -SRC_C += external_flash/external_flash.c external_flash/spi_flash.c -endif -ifeq ($(QSPI_FLASH_FILESYSTEM),1) -SRC_C += external_flash/external_flash.c external_flash/qspi_flash.c -endif - SRC_COMMON_HAL = \ board/__init__.c \ busio/__init__.c \ @@ -339,7 +318,6 @@ SRC_COMMON_HAL = \ rotaryio/IncrementalEncoder.c \ rtc/__init__.c \ rtc/RTC.c \ - storage/__init__.c \ supervisor/__init__.c \ supervisor/Runtime.c \ time/__init__.c \ @@ -352,10 +330,8 @@ SRC_COMMON_HAL = \ pulseio/PulseIn.c \ pulseio/PulseOut.c \ pulseio/PWMOut.c \ - usb_hid/__init__.c \ - usb_hid/Device.c \ touchio/__init__.c \ - touchio/TouchIn.c \ + touchio/TouchIn.c ifeq ($(INTERNAL_LIBM),1) SRC_LIBM = $(addprefix lib/,\ @@ -412,12 +388,17 @@ SRC_SHARED_MODULE = \ _stage/__init__.c \ _stage/Layer.c \ _stage/Text.c \ + storage/__init__.c \ os/__init__.c \ random/__init__.c \ - storage/__init__.c \ struct/__init__.c \ uheap/__init__.c \ - ustack/__init__.c + ustack/__init__.c \ + usb_hid/__init__.c \ + usb_hid/Device.c + + # usb_midi/__init__.c + # usb_midi/Port.c ifeq ($(MICROPY_PY_NETWORK),1) SRC_SHARED_MODULE += socket/__init__.c network/__init__.c @@ -489,21 +470,6 @@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(STEPECHO) "Create $@" $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -c -o $@ $^ -$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate - -.INTERMEDIATE: autogen_usb_descriptor.intermediate - -autogen_usb_descriptor.intermediate: tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) - $(STEPECHO) "GEN $@" - $(Q)install -d $(BUILD)/genhdr - $(Q)$(PYTHON3) tools/gen_usb_descriptor.py \ - --manufacturer $(USB_MANUFACTURER)\ - --product $(USB_PRODUCT)\ - --vid $(USB_VID)\ - --pid $(USB_PID)\ - --output_c_file $(BUILD)/autogen_usb_descriptor.c\ - --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h - deploy: $(BUILD)/firmware.bin $(ECHO) "Writing $< to the board" $(BOSSAC) -u $< diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 3cf6831a3..099cb8b23 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -27,8 +27,7 @@ #include "audio_dma.h" #include "tick.h" -#include "usb.h" -#include "usb_mass_storage.h" +#include "supervisor/usb.h" #include "shared-module/displayio/__init__.h" #include "shared-module/network/__init__.h" @@ -45,8 +44,8 @@ void run_background_tasks(void) { #if MICROPY_PY_NETWORK network_module_background(); #endif - usb_msc_background(); - usb_cdc_background(); + usb_background(); + last_finished_tick = ticks_ms; } diff --git a/ports/atmel-samd/boards/arduino_zero/board.c b/ports/atmel-samd/boards/arduino_zero/board.c index 2dc1683ea..770bc8259 100644 --- a/ports/atmel-samd/boards/arduino_zero/board.c +++ b/ports/atmel-samd/boards/arduino_zero/board.c @@ -30,13 +30,6 @@ void board_init(void) { - gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_TX, true); - - gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_RX, true); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h index 1382d4736..56e4dbcec 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -1,16 +1,14 @@ #define MICROPY_HW_BOARD_NAME "Arduino Zero" #define MICROPY_HW_MCU_NAME "samd21g18" -// #define MICROPY_HW_LED_MSC PIN_PA17 // red -#define MICROPY_HW_LED_TX PIN_PA27 -#define MICROPY_HW_LED_RX PIN_PB03 +// #define MICROPY_HW_LED_MSC &pin_PA17 // red +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PB03 #define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA27) #define MICROPY_PORT_B (PORT_PB03) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 5077840cb..6dfaf87e9 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -8,52 +8,25 @@ #define SPI_FLASH_BAUDRATE (8000000) // On-board flash -#define SPI_FLASH_MOSI_PIN PIN_PA20 -#define SPI_FLASH_MISO_PIN PIN_PA16 -#define SPI_FLASH_SCK_PIN PIN_PA21 -#define SPI_FLASH_CS_PIN PIN_PB22 - -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA20D_SERCOM3_PAD2 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA21D_SERCOM3_PAD3 -#define SPI_FLASH_SERCOM SERCOM3 -#define SPI_FLASH_SERCOM_INDEX 3 -#define SPI_FLASH_MOSI_PAD 2 -#define SPI_FLASH_MISO_PAD 0 -#define SPI_FLASH_SCK_PAD 3 - -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 1 -#define SPI_FLASH_DIPO 0 // same as MISO PAD +#define SPI_FLASH_MOSI_PIN &pin_PA20 +#define SPI_FLASH_MISO_PIN &pin_PA16 +#define SPI_FLASH_SCK_PIN &pin_PA21 +#define SPI_FLASH_CS_PIN &pin_PB22 // These are pins not to reset. // PA24 and PA25 are USB. -#define MICROPY_PORT_A (PORT_PA16 | PORT_PA20 | PORT_PA21 | PORT_PA24 | PORT_PA25) -#define MICROPY_PORT_B (PORT_PB22) +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) #define SPEAKER_ENABLE_PIN (&pin_PA30) -#include "external_flash/devices.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk index 831106adc..e5665afb6 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "CircuitPlayground Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 638a6646c..250300858 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -11,52 +11,24 @@ #define SPI_FLASH_BAUDRATE (8000000) // On-board flash -#define SPI_FLASH_MOSI_PIN PIN_PA20 -#define SPI_FLASH_MISO_PIN PIN_PA16 -#define SPI_FLASH_SCK_PIN PIN_PA21 -#define SPI_FLASH_CS_PIN PIN_PB22 - -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA20D_SERCOM3_PAD2 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA21D_SERCOM3_PAD3 -#define SPI_FLASH_SERCOM SERCOM3 -#define SPI_FLASH_SERCOM_INDEX 3 -#define SPI_FLASH_MOSI_PAD 2 -#define SPI_FLASH_MISO_PAD 0 -#define SPI_FLASH_SCK_PAD 3 - -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 1 -#define SPI_FLASH_DIPO 0 // same as MISO PAD +#define SPI_FLASH_MOSI_PIN &pin_PA20 +#define SPI_FLASH_MISO_PIN &pin_PA16 +#define SPI_FLASH_SCK_PIN &pin_PA21 +#define SPI_FLASH_CS_PIN &pin_PB22 // These are pins not to reset. -// PA24 and PA25 are USB. -#define MICROPY_PORT_A (PORT_PA16 | PORT_PA20 | PORT_PA21 | PORT_PA24 | PORT_PA25) -#define MICROPY_PORT_B (PORT_PB22) +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) #define SPEAKER_ENABLE_PIN (&pin_PA30) -#include "external_flash/devices.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index 972c4b10d..b07d63984 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "CircuitPlayground Express with Crickit libraries" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" # Turn off longints for Crickit build to make room for additional frozen libs. LONGINT_IMPL = NONE diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h index c8b5c56ee..c28c4aafb 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h @@ -3,12 +3,10 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Adalogger" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h index dcac9749d..d66efb36f 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h @@ -4,12 +4,10 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Basic" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h index 03d0ba9bd..1f02ee995 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h @@ -3,35 +3,16 @@ #define MICROPY_HW_NEOPIXEL (&pin_PA06) -// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA08 -#define SPI_FLASH_MISO_PIN PIN_PA14 -#define SPI_FLASH_SCK_PIN PIN_PA09 -#define SPI_FLASH_CS_PIN PIN_PA13 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1 -#define SPI_FLASH_SERCOM SERCOM2 -#define SPI_FLASH_SERCOM_INDEX 2 -#define SPI_FLASH_MOSI_PAD 0 -#define SPI_FLASH_MISO_PAD 2 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0 -#define SPI_FLASH_DIPO 2 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (PORT_PA06) #define MICROPY_PORT_B ( 0 ) #define MICROPY_PORT_C ( 0 ) -#include "external_flash/external_flash.h" // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. @@ -39,14 +20,6 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA23) diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index e9f9b09fb..57ce96285 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h index 756462013..b5544e253 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h @@ -3,50 +3,22 @@ #define MICROPY_HW_NEOPIXEL (&pin_PA06) -// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA08 -#define SPI_FLASH_MISO_PIN PIN_PA14 -#define SPI_FLASH_SCK_PIN PIN_PA09 -#define SPI_FLASH_CS_PIN PIN_PA13 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1 -#define SPI_FLASH_SERCOM SERCOM2 -#define SPI_FLASH_SERCOM_INDEX 2 -#define SPI_FLASH_MOSI_PAD 0 -#define SPI_FLASH_MISO_PAD 2 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0 -#define SPI_FLASH_DIPO 2 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (PORT_PA06) #define MICROPY_PORT_B ( 0 ) #define MICROPY_PORT_C ( 0 ) -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA23) diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk index 7ff5337a3..f773bcb57 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h index 4a530ed29..c385a97ea 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h @@ -4,12 +4,10 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM69" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h index 3a6f28c12..1e3a0bda0 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h @@ -4,12 +4,10 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM9x" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h index a7a2d7de0..6bf1df156 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h @@ -5,49 +5,22 @@ #define MICROPY_HW_NEOPIXEL (&pin_PA06) -// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA08 -#define SPI_FLASH_MISO_PIN PIN_PA14 -#define SPI_FLASH_SCK_PIN PIN_PA09 -#define SPI_FLASH_CS_PIN PIN_PA13 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1 -#define SPI_FLASH_SERCOM SERCOM2 -#define SPI_FLASH_SERCOM_INDEX 2 -#define SPI_FLASH_MOSI_PAD 0 -#define SPI_FLASH_MISO_PAD 2 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0 -#define SPI_FLASH_DIPO 2 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (PORT_PA06) #define MICROPY_PORT_B ( 0 ) #define MICROPY_PORT_C ( 0 ) -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES S25FL064L - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PA23) #define DEFAULT_I2C_BUS_SDA (&pin_PA22) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 79bf2d34a..4bae6ffa7 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "Feather M0 Supersized" USB_MANUFACTURER = "Dave Astels" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index e9e921b4d..98906a844 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -23,15 +23,8 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q16C - #define EXTERNAL_FLASH_QSPI_DUAL -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA13) diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index bbc5985a9..3f2cb6ce4 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -5,6 +5,9 @@ USB_PRODUCT = "Feather M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 + +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51J19A diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h index 32c549953..c4e025178 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h @@ -3,50 +3,22 @@ #define MICROPY_HW_NEOPIXEL (&pin_PA22) -// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA31 -#define SPI_FLASH_MISO_PIN PIN_PA30 -#define SPI_FLASH_SCK_PIN PIN_PA17 -#define SPI_FLASH_CS_PIN PIN_PA28 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA31D_SERCOM1_PAD3 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA30D_SERCOM1_PAD2 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17C_SERCOM1_PAD1 -#define SPI_FLASH_SERCOM SERCOM1 -#define SPI_FLASH_SERCOM_INDEX 1 -#define SPI_FLASH_MOSI_PAD 3 -#define SPI_FLASH_MISO_PAD 2 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 2 -#define SPI_FLASH_DIPO 2 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PA31 +#define SPI_FLASH_MISO_PIN &pin_PA30 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA28 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA17 | PORT_PA22 | PORT_PA24 | PORT_PA25 | PORT_PA28 | PORT_PA30 | PORT_PA31) +#define MICROPY_PORT_A (PORT_PA22) #define MICROPY_PORT_B ( 0 ) #define MICROPY_PORT_C ( 0 ) -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA13) diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk index 42177d274..634a9ede7 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "Feather RadioFruit Zigbee" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMR21G18A diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h index 1ec217096..08d1803f2 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h @@ -18,8 +18,6 @@ #define DEFAULT_UART_BUS_RX (&pin_PA05) #define DEFAULT_UART_BUS_TX (&pin_PA04) -#include "internal_flash.h" - #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) #define IGNORE_PIN_PA03 1 diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/board.c b/ports/atmel-samd/boards/grandcentral_m4_express/board.c index 360b5d8f9..7599f02b8 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/board.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/board.c @@ -29,13 +29,6 @@ #include "hal/include/hal_gpio.h" void board_init(void) { - gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_TX, true); - - gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_RX, true); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h index 231bf20e0..0d2d65ba5 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h @@ -5,8 +5,8 @@ // This is for Rev A which is green -#define MICROPY_HW_LED_TX PIN_PC30 -#define MICROPY_HW_LED_RX PIN_PC31 +#define MICROPY_HW_LED_TX &(pin_PC30) +#define MICROPY_HW_LED_RX &(pin_PC31) #define MICROPY_HW_NEOPIXEL (&pin_PC24) @@ -27,13 +27,6 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q64C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PB21) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk index 3e8717ecf..2605c9f55 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk @@ -5,6 +5,9 @@ USB_PRODUCT = "Grand Central M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 + +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q64C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51P20A diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h index 8450882b9..7dd4bf7c4 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -3,51 +3,22 @@ #define MICROPY_HW_NEOPIXEL (&pin_PA12) -// Clock rates are off: Saleae reads 12MHz which is the limit even though we set it to the safer 8MHz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PB10 -#define SPI_FLASH_MISO_PIN PIN_PA13 -#define SPI_FLASH_SCK_PIN PIN_PB11 -#define SPI_FLASH_CS_PIN PIN_PA07 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB10D_SERCOM4_PAD2 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA13D_SERCOM4_PAD1 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB11D_SERCOM4_PAD3 -#define SPI_FLASH_SERCOM SERCOM4 -#define SPI_FLASH_SERCOM_INDEX 4 -#define SPI_FLASH_MOSI_PAD 2 -#define SPI_FLASH_MISO_PAD 1 -#define SPI_FLASH_SCK_PAD 3 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0x1 -#define SPI_FLASH_DIPO 1 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PB10 +#define SPI_FLASH_MISO_PIN &pin_PA13 +#define SPI_FLASH_SCK_PIN &pin_PB11 +#define SPI_FLASH_CS_PIN &pin_PA07 // These are pins not to reset. -#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA07 | PORT_PA12 | PORT_PA13 | PORT_PA24 | PORT_PA25 | PORT_PA27 | PORT_PA28) -#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 | PORT_PB23 ) +#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA12 | PORT_PA27 | PORT_PA28) +#define MICROPY_PORT_B ( PORT_PB22 | PORT_PB23 ) #define MICROPY_PORT_C ( 0 ) -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 - -#define EXTERNAL_FLASH_DEVICES W25Q64JV_IQ, \ - GD25Q64C - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PA17) #define DEFAULT_I2C_BUS_SDA (&pin_PA16) diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 817d93943..37f1bdef0 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "HalloWing M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h index f56f57c46..4de28d388 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h @@ -5,32 +5,14 @@ #define MICROPY_HW_APA102_MOSI (&pin_PA01) #define MICROPY_HW_APA102_SCK (&pin_PA00) -// Saleae reads 12mhz which is the limit even though we set it to the safer 8mhz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PB22 -#define SPI_FLASH_MISO_PIN PIN_PB03 -#define SPI_FLASH_SCK_PIN PIN_PB23 -#define SPI_FLASH_CS_PIN PIN_PA27 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB22D_SERCOM5_PAD2 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB03D_SERCOM5_PAD1 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB23D_SERCOM5_PAD3 -#define SPI_FLASH_SERCOM SERCOM5 -#define SPI_FLASH_SERCOM_INDEX 5 -#define SPI_FLASH_MOSI_PAD 2 -#define SPI_FLASH_MISO_PAD 1 -#define SPI_FLASH_SCK_PAD 3 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 1 -#define SPI_FLASH_DIPO 1 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA27 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA27 | PORT_PA24 | PORT_PA25) -#define MICROPY_PORT_B (PORT_PB22 | PORT_PB23 | PORT_PB03 ) +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01) +#define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) // If you change this, then make sure to update the linker scripts as well to @@ -39,14 +21,6 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES W25Q16FW, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PA23) #define DEFAULT_I2C_BUS_SDA (&pin_PA22) diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index 9f62ae839..8fcf5208f 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "ItsyBitsy M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C" LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21G18A diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h index e47d5390d..5bbfec9ce 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h @@ -25,13 +25,6 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q16C - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PA13) #define DEFAULT_I2C_BUS_SDA (&pin_PA12) diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index 27f5ea2b8..2afff5965 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "ItsyBitsy M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51G19A diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h index 3ce00b04f..f07eb9cce 100644 --- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -1,15 +1,11 @@ #define MICROPY_HW_BOARD_NAME "Meow Meow" #define MICROPY_HW_MCU_NAME "samd21g18" - // These are pins not to reset. -// PA24 and PA25 are USB. -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h index 40ef3ce78..28bb1f293 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -1,37 +1,22 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Metro M0 Express" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_HW_LED_TX PIN_PA27 -//#define MICROPY_HW_LED_RX PIN_PA31 +//#define MICROPY_HW_LED_TX &pin_PA27 +//#define MICROPY_HW_LED_RX &pin_PA31 #define MICROPY_HW_NEOPIXEL (&pin_PA30) // Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. #define SPI_FLASH_BAUDRATE (8000000) -#define SPI_FLASH_MOSI_PIN PIN_PB22 -#define SPI_FLASH_MISO_PIN PIN_PB03 -#define SPI_FLASH_SCK_PIN PIN_PB23 -#define SPI_FLASH_CS_PIN PIN_PA13 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB22D_SERCOM5_PAD2 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB03D_SERCOM5_PAD1 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB23D_SERCOM5_PAD3 -#define SPI_FLASH_SERCOM SERCOM5 -#define SPI_FLASH_SERCOM_INDEX 5 -#define SPI_FLASH_MOSI_PAD 2 -#define SPI_FLASH_MISO_PAD 1 -#define SPI_FLASH_SCK_PAD 3 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 1 -#define SPI_FLASH_DIPO 1 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA13 |PORT_PA24 | PORT_PA25 | PORT_PA27 | PORT_PA30 | PORT_PA31) -#define MICROPY_PORT_B (PORT_PB03 | PORT_PB22 | PORT_PB23) +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31) +#define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) // If you change this, then make sure to update the linker scripts as well to @@ -40,14 +25,6 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 2 -#define EXTERNAL_FLASH_DEVICES S25FL216K, \ - GD25Q16C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA23) diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index 40a0092ac..49a94144b 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -12,3 +12,7 @@ CHIP_FAMILY = samd21 MICROPY_PY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" diff --git a/ports/atmel-samd/boards/metro_m4_express/board.c b/ports/atmel-samd/boards/metro_m4_express/board.c index a98385d29..0f60736a2 100644 --- a/ports/atmel-samd/boards/metro_m4_express/board.c +++ b/ports/atmel-samd/boards/metro_m4_express/board.c @@ -29,13 +29,6 @@ #include "hal/include/hal_gpio.h" void board_init(void) { - gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_TX, true); - - gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_RX, true); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index f1201c8a0..06feb1a22 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -5,16 +5,16 @@ // This is for Rev F which is green -#define MICROPY_HW_LED_TX PIN_PA27 -#define MICROPY_HW_LED_RX PIN_PB06 +#define MICROPY_HW_LED_TX (&pin_PA27) +#define MICROPY_HW_LED_RX (&pin_PB06) #define MICROPY_HW_NEOPIXEL (&pin_PB22) // These are pins not to reset. -// QSPI Data pins and TX LED -#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PORT_PA27) -// RX LED, QSPI CS, QSPI SCK and NeoPixel pin -#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB22) +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB22) #define MICROPY_PORT_C (0) #define MICROPY_PORT_D (0) @@ -26,13 +26,6 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 3 -#define EXTERNAL_FLASH_DEVICES S25FL116K, S25FL216K, GD25Q16C - -#include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PB03) diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index cbc89159f..633856362 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -5,6 +5,9 @@ USB_PRODUCT = "Metro M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 3 +EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" + LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51J19A diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h index 15979ae77..cbbd4b569 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h @@ -15,8 +15,6 @@ // A number of modules are removed for pIRKey to make room for frozen libraries. #define PIRKEY_M0 (1) -#include "internal_flash.h" - #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) #define IGNORE_PIN_PA02 1 diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h index 1464d100c..6870b86ba 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -26,13 +26,6 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q64C - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PB08) #define DEFAULT_I2C_BUS_SDA (&pin_PB09) diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk index 3841a87c7..7094b79be 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT = "Trellis M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q64C LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD51G19A diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h index 9036f8e7b..24f3004e9 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -9,8 +9,6 @@ #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h index 8e3fdd7a8..dfbd873b6 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h @@ -5,56 +5,24 @@ // #define MICROPY_HW_APA102_MOSI (&pin_PA00) // #define MICROPY_HW_APA102_SCK (&pin_PA01) -// Salae reads 12mhz which is the limit even though we set it to the -// safer 8mhz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA16 -#define SPI_FLASH_MISO_PIN PIN_PA19 -#define SPI_FLASH_SCK_PIN PIN_PA17 -#define SPI_FLASH_CS_PIN PIN_PA11 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA19D_SERCOM3_PAD3 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17D_SERCOM3_PAD1 -#define SPI_FLASH_SERCOM SERCOM3 -#define SPI_FLASH_SERCOM_INDEX 3 -#define SPI_FLASH_MOSI_PAD 0 -#define SPI_FLASH_MISO_PAD 3 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0 -#define SPI_FLASH_DIPO 3 // same as MISO pad - -#define SPI_FLASH_CS PIN_PA11 +#define SPI_FLASH_MOSI_PIN &pin_PA16 +#define SPI_FLASH_MISO_PIN &pin_PA19 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA11 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA11 | PORT_PA16 |\ - PORT_PA17 | PORT_PA18 | PORT_PA19 | PORT_PA24 |\ - PORT_PA25) +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA18) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) #define CALIBRATE_CRYSTALLESS 1 -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES W25Q32BV - -#include "external_flash/external_flash.h" - #define DEFAULT_I2C_BUS_SCL (&pin_PA09) #define DEFAULT_I2C_BUS_SDA (&pin_PA08) diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk index d97aa08ab..c9c196da7 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_PRODUCT="Trinket M0 Haxpress" USB_MANUFACTURER="Radomir Dopieralski" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = W25Q32BV LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21E18A diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h index ed822952d..c22a3f735 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h @@ -1,53 +1,24 @@ #define MICROPY_HW_BOARD_NAME "uGame10" #define MICROPY_HW_MCU_NAME "samd21e18" -// Salae reads 12mhz which is the limit even though we set it to the -// safer 8mhz. -#define SPI_FLASH_BAUDRATE (8000000) - -#define SPI_FLASH_MOSI_PIN PIN_PA16 -#define SPI_FLASH_MISO_PIN PIN_PA19 -#define SPI_FLASH_SCK_PIN PIN_PA17 -#define SPI_FLASH_CS_PIN PIN_PA18 -#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA16D_SERCOM3_PAD0 -#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA19D_SERCOM3_PAD3 -#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA17D_SERCOM3_PAD1 -#define SPI_FLASH_SERCOM SERCOM3 -#define SPI_FLASH_SERCOM_INDEX 3 -#define SPI_FLASH_MOSI_PAD 0 -#define SPI_FLASH_MISO_PAD 3 -#define SPI_FLASH_SCK_PAD 1 -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -#define SPI_FLASH_DOPO 0 -#define SPI_FLASH_DIPO 3 // same as MISO pad +#define SPI_FLASH_MOSI_PIN &pin_PA16 +#define SPI_FLASH_MISO_PIN &pin_PA19 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA18 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA16 | PORT_PA17 | PORT_PA18 | PORT_PA19 |\ - PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) #define CALIBRATE_CRYSTALLESS 1 -#include "external_flash/external_flash.h" - // If you change this, then make sure to update the linker scripts as well to // make sure you don't overwrite code. #define CIRCUITPY_INTERNAL_NVM_SIZE 256 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES S25FL216K - -#include "external_flash/external_flash.h" - #define EXTRA_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \ diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index 2386531f9..6dc0af9cf 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_PRODUCT = "uGame10" USB_MANUFACTURER = "Radomir Dopieralski" SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = S25FL216K LONGINT_IMPL = MPZ CHIP_VARIANT = SAMD21E18A diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index a292f9e3d..4de34c975 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -31,6 +31,8 @@ #include "hpl_sercom_config.h" #include "peripheral_clk_config.h" +#include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" #include "hal/include/hal_gpio.h" #include "hal/include/hal_spi_m_sync.h" #include "hal/include/hpl_spi_m_sync.h" @@ -39,6 +41,43 @@ #include "samd/dma.h" #include "samd/sercom.h" +bool never_reset_sercoms[SERCOM_INST_NUM]; + +void never_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = true; + break; + } + } +} + +void reset_sercoms(void) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (never_reset_sercoms[i]) { + continue; + } + #ifdef MICROPY_HW_APA102_SERCOM + if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) { + continue; + } + #endif + #ifdef CIRCUITPY_DISPLAYIO + // TODO(tannewt): Make this dynamic. + if (sercom_instances[i] == board_display_obj.bus.spi_desc.dev.prvt) { + continue; + } + #endif + // SWRST is same for all modes of SERCOMs. + sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1; + } +} + + void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { @@ -186,6 +225,14 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, spi_m_sync_enable(&self->spi_desc); } +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + never_reset_sercom(self->spi_desc.dev.prvt); + + never_reset_pin_number(self->clock_pin); + never_reset_pin_number(self->MOSI_pin); + never_reset_pin_number(self->MISO_pin); +} + bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock_pin == NO_PIN; } diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h index 2fced6d64..56d163a9d 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.h +++ b/ports/atmel-samd/common-hal/busio/SPI.h @@ -42,4 +42,7 @@ typedef struct { uint8_t MISO_pin; } busio_spi_obj_t; +void reset_sercoms(void); + + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 0f179a6c1..9af5aeaf7 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -43,8 +43,12 @@ bool apa102_mosi_in_use; bool speaker_enable_in_use; #endif +#define PORT_COUNT (PORT_BITS / 32 + 1) + +STATIC uint32_t never_reset_pins[PORT_COUNT]; + void reset_all_pins(void) { - uint32_t pin_mask[PORT_BITS / 32 + 1] = PORT_OUT_IMPLEMENTED; + uint32_t pin_mask[PORT_COUNT] = PORT_OUT_IMPLEMENTED; // Do not full reset USB or SWD lines. pin_mask[0] &= ~(PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31); @@ -53,6 +57,11 @@ void reset_all_pins(void) { pin_mask[0] &= ~(PORT_PA31); #endif + for (uint32_t i = 0; i < PORT_COUNT; i++) { + pin_mask[i] &= ~(PORT_PA31); + pin_mask[i] &= ~never_reset_pins[i]; + } + gpio_set_port_direction(GPIO_PORTA, pin_mask[0] & ~MICROPY_PORT_A, GPIO_DIRECTION_OFF); gpio_set_port_direction(GPIO_PORTB, pin_mask[1] & ~MICROPY_PORT_B, GPIO_DIRECTION_OFF); #if PORT_BITS > 64 @@ -91,6 +100,10 @@ void reset_all_pins(void) { #endif } +void never_reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] |= 1 << GPIO_PIN(pin_number); +} + void reset_pin_number(uint8_t pin_number) { if (pin_number >= PORT_BITS) { return; diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h index dcd80997e..f798ea300 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.h +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h @@ -43,6 +43,7 @@ void reset_all_pins(void); // reset_pin_number takes the pin number instead of the pointer so that objects don't // need to store a full pointer. void reset_pin_number(uint8_t pin_number); +void never_reset_pin_number(uint8_t pin_number); void claim_pin(const mcu_pin_obj_t* pin); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 746207787..0ca3a0835 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -107,7 +107,6 @@ const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { // This maps MCU pin names to pin objects. STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { -// Pins in datasheet order. #if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00) { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) }, #endif @@ -120,24 +119,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03) { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, #endif -#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04) - { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, -#endif -#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05) - { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, -#endif -#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06) - { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, -#endif -#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07) - { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, -#endif -#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08) - { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, -#endif -#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09) - { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, -#endif #if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04) { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, #endif @@ -162,26 +143,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11) { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) }, #endif -#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10) - { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, -#endif -#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11) - { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, -#endif -#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12) - { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, -#endif -#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13) - { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, -#endif -#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14) - { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, -#endif - -// Second page. -#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15) - { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, -#endif #if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12) { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) }, #endif @@ -206,12 +167,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19) { MP_ROM_QSTR(MP_QSTR_PA19), MP_ROM_PTR(&pin_PA19) }, #endif -#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16) - { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) }, -#endif -#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) - { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) }, -#endif #if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20) { MP_ROM_QSTR(MP_QSTR_PA20), MP_ROM_PTR(&pin_PA20) }, #endif @@ -230,12 +185,6 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25) { MP_ROM_QSTR(MP_QSTR_PA25), MP_ROM_PTR(&pin_PA25) }, #endif -#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) - { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) }, -#endif -#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23) - { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) }, -#endif #if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27) { MP_ROM_QSTR(MP_QSTR_PA27), MP_ROM_PTR(&pin_PA27) }, #endif @@ -248,12 +197,7 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31) { MP_ROM_QSTR(MP_QSTR_PA31), MP_ROM_PTR(&pin_PA31) }, #endif -#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30) - { MP_ROM_QSTR(MP_QSTR_PB30), MP_ROM_PTR(&pin_PB30) }, -#endif -#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31) - { MP_ROM_QSTR(MP_QSTR_PB31), MP_ROM_PTR(&pin_PB31) }, -#endif + #if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00) { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, #endif @@ -266,14 +210,176 @@ STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { #if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03) { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, #endif +#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04) + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, +#endif +#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05) + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, +#endif +#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06) + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, +#endif +#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07) + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, +#endif +#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08) + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, +#endif +#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09) + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, +#endif +#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10) + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, +#endif +#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11) + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, +#endif +#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12) + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, +#endif +#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13) + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, +#endif +#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14) + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, +#endif +#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15) + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, +#endif +#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16) + { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) }, +#endif +#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) + { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) }, +#endif +#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) + { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) }, +#endif +#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23) + { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) }, +#endif +#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30) + { MP_ROM_QSTR(MP_QSTR_PB30), MP_ROM_PTR(&pin_PB30) }, +#endif +#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31) + { MP_ROM_QSTR(MP_QSTR_PB31), MP_ROM_PTR(&pin_PB31) }, +#endif + +// These are SAMD51 specific so we assume we want them in RAM +#if defined(PIN_PC00) + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, +#endif +#if defined(PIN_PC01) + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, +#endif +#if defined(PIN_PC02) + { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) }, +#endif +#if defined(PIN_PC03) + { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) }, +#endif +#if defined(PIN_PC04) + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, +#endif +#if defined(PIN_PC05) + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, +#endif +#if defined(PIN_PC06) + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, +#endif +#if defined(PIN_PC07) + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, +#endif +#if defined(PIN_PC10) + { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) }, +#endif +#if defined(PIN_PC11) + { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) }, +#endif +#if defined(PIN_PC12) + { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) }, +#endif +#if defined(PIN_PC13) + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, +#endif +#if defined(PIN_PC14) + { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) }, +#endif +#if defined(PIN_PC15) + { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) }, +#endif #if defined(PIN_PC16) { MP_ROM_QSTR(MP_QSTR_PC16), MP_ROM_PTR(&pin_PC16) }, #endif +#if defined(PIN_PC17) + { MP_ROM_QSTR(MP_QSTR_PC17), MP_ROM_PTR(&pin_PC17) }, +#endif #if defined(PIN_PC18) { MP_ROM_QSTR(MP_QSTR_PC18), MP_ROM_PTR(&pin_PC18) }, #endif #if defined(PIN_PC19) { MP_ROM_QSTR(MP_QSTR_PC19), MP_ROM_PTR(&pin_PC19) }, #endif +#if defined(PIN_PC20) + { MP_ROM_QSTR(MP_QSTR_PC20), MP_ROM_PTR(&pin_PC20) }, +#endif +#if defined(PIN_PC21) + { MP_ROM_QSTR(MP_QSTR_PC21), MP_ROM_PTR(&pin_PC21) }, +#endif +#if defined(PIN_PC22) + { MP_ROM_QSTR(MP_QSTR_PC22), MP_ROM_PTR(&pin_PC22) }, +#endif +#if defined(PIN_PC23) + { MP_ROM_QSTR(MP_QSTR_PC23), MP_ROM_PTR(&pin_PC23) }, +#endif +#if defined(PIN_PC24) + { MP_ROM_QSTR(MP_QSTR_PC24), MP_ROM_PTR(&pin_PC24) }, +#endif +#if defined(PIN_PC25) + { MP_ROM_QSTR(MP_QSTR_PC25), MP_ROM_PTR(&pin_PC25) }, +#endif +#if defined(PIN_PC26) + { MP_ROM_QSTR(MP_QSTR_PC26), MP_ROM_PTR(&pin_PC26) }, +#endif +#if defined(PIN_PC27) + { MP_ROM_QSTR(MP_QSTR_PC27), MP_ROM_PTR(&pin_PC27) }, +#endif +#if defined(PIN_PC28) + { MP_ROM_QSTR(MP_QSTR_PC28), MP_ROM_PTR(&pin_PC28) }, +#endif +#if defined(PIN_PC30) + { MP_ROM_QSTR(MP_QSTR_PC30), MP_ROM_PTR(&pin_PC30) }, +#endif +#if defined(PIN_PC31) + { MP_ROM_QSTR(MP_QSTR_PC31), MP_ROM_PTR(&pin_PC31) }, +#endif + +#if defined(PIN_PD00) + { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) }, +#endif +#if defined(PIN_PD01) + { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) }, +#endif +#if defined(PIN_PD08) + { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) }, +#endif +#if defined(PIN_PD09) + { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) }, +#endif +#if defined(PIN_PD10) + { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) }, +#endif +#if defined(PIN_PD11) + { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) }, +#endif +#if defined(PIN_PD12) + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, +#endif +#if defined(PIN_PD20) + { MP_ROM_QSTR(MP_QSTR_PD20), MP_ROM_PTR(&pin_PD20) }, +#endif +#if defined(PIN_PD21) + { MP_ROM_QSTR(MP_QSTR_PD21), MP_ROM_PTR(&pin_PD21) }, +#endif }; MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); diff --git a/ports/atmel-samd/common-hal/storage/__init__.c b/ports/atmel-samd/common-hal/storage/__init__.c deleted file mode 100644 index 501a19dd7..000000000 --- a/ports/atmel-samd/common-hal/storage/__init__.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 - -#include "flash_api.h" -#include "py/mperrno.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/storage/__init__.h" -#include "supervisor/filesystem.h" -#include "supervisor/shared/translate.h" -#include "usb.h" - -extern volatile bool mp_msc_enabled; - -void common_hal_storage_remount(const char* mount_path, bool readonly) { - if (strcmp(mount_path, "/") != 0) { - mp_raise_OSError(MP_EINVAL); - } - - // TODO(dhalbert): is this is a good enough check? It checks for - // CDC enabled. There is no "MSC enabled" check. - if (usb_connected()) { - mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active.")); - } - - flash_set_usb_writable(readonly); -} - -void common_hal_storage_erase_filesystem(void) { - filesystem_init(false, true); // Force a re-format. - common_hal_mcu_reset(); - // We won't actually get here, since we're resetting. -} diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c index 2636fe646..ea663f897 100755 --- a/ports/atmel-samd/common-hal/supervisor/Runtime.c +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -26,13 +26,12 @@ #include #include "shared-bindings/supervisor/Runtime.h" -#include "usb.h" +#include "supervisor/serial.h" bool common_hal_get_serial_connected(void) { - return (bool) usb_connected(); + return (bool) serial_connected(); } bool common_hal_get_serial_bytes_available(void) { - return (bool) usb_bytes_available(); + return (bool) serial_bytes_available(); } - diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.c b/ports/atmel-samd/common-hal/usb_hid/Device.c deleted file mode 100644 index 31bace018..000000000 --- a/ports/atmel-samd/common-hal/usb_hid/Device.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 - -#include "common-hal/usb_hid/Device.h" - -#include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/usb_hid/Device.h" -#include "supervisor/shared/translate.h" -#include "genhdr/autogen_usb_descriptor.h" - -#include "tick.h" - -#include "usb/class/hid/device/hiddf_generic.h" - -static uint32_t usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { - - int32_t status; - - // Don't get stuck if USB fails in some way; timeout after a while. - uint64_t end_ticks = ticks_ms + 2000; - - while (ticks_ms < end_ticks) { - status = usb_d_ep_get_status(self->endpoint, NULL); - if (status == USB_BUSY) { - continue; - } - if (status == USB_OK) { - break; - } - // Some error. Give up. - return status; - } - - // Copy the data only when endpoint is ready to send. The previous - // buffer load gets zero'd out when transaction completes, so if - // you copy before it's ready, only zeros will get sent. - - // Prefix with a report id if one is supplied. - if (self->report_id > 0) { - self->report_buffer[0] = self->report_id; - memcpy(&(self->report_buffer[1]), report, len); - return hiddf_generic_write(self->report_buffer, len + 1); - } else { - memcpy(self->report_buffer, report, len); - return hiddf_generic_write(self->report_buffer, len); - } - -} - -void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { - if (len != self->report_length) { - mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length); - } - int32_t status = usb_hid_send_report(self, report, len); - if (status != ERR_NONE) { - mp_raise_msg(&mp_type_OSError, status == USB_BUSY ? translate("USB Busy") : translate("USB Error")); - } -} - -uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { - return self->usage_page; -} - -uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { - return self->usage; -} - - -void usb_hid_init() { -} - -void usb_hid_reset() { - // We don't actually reset. We just set a report that is empty to prevent - // long keypresses and such. - uint8_t report[USB_HID_MAX_REPORT_LENGTH] = {0}; - - for (size_t i = 0; i < USB_HID_NUM_DEVICES; i++) { - usb_hid_send_report(&usb_hid_devices[i], report, usb_hid_devices[i].report_length); - } -} diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.h b/ports/atmel-samd/common-hal/usb_hid/Device.h deleted file mode 100644 index b81c0e709..000000000 --- a/ports/atmel-samd/common-hal/usb_hid/Device.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef COMMON_HAL_USB_HID_DEVICE_H -#define COMMON_HAL_USB_HID_DEVICE_H - -#include -#include - -#include "py/obj.h" - -#include "genhdr/autogen_usb_descriptor.h" - -typedef struct { - mp_obj_base_t base; - uint8_t* report_buffer; - uint8_t endpoint; - uint8_t report_id; // If non-zero, prefix report with given id. - uint8_t report_length; // Length not including Report ID. - uint8_t usage_page; - uint8_t usage; - -} usb_hid_device_obj_t; - -extern usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES]; - -void usb_hid_init(void); -void usb_hid_reset(void); - -#endif // COMMON_HAL_USB_HID_DEVICE_H diff --git a/ports/atmel-samd/common-hal/usb_hid/__init__.c b/ports/atmel-samd/common-hal/usb_hid/__init__.c deleted file mode 100644 index 770d221c7..000000000 --- a/ports/atmel-samd/common-hal/usb_hid/__init__.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "py/obj.h" -#include "py/mphal.h" -#include "py/runtime.h" - -#include "common-hal/usb_hid/Device.h" - -#include "shared-bindings/usb_hid/Device.h" - -#include "genhdr/autogen_usb_descriptor.h" - -// Buffers are report size + 1 to include the Report ID prefix byte if needed. -#ifdef USB_HID_REPORT_ID_KEYBOARD -static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD + 1]; -#endif -#ifdef USB_HID_REPORT_ID_MOUSE -static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE + 1]; -#endif -#ifdef USB_HID_REPORT_ID_CONSUMER -static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER + 1]; -#endif -#ifdef USB_HID_REPORT_ID_SYS_CONTROL -static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL + 1]; -#endif -#ifdef USB_HID_REPORT_ID_GAMEPAD -static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD + 1]; -#endif -#ifdef USB_HID_REPORT_ID_DIGITIZER -static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER + 1]; -#endif - -usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = { -#ifdef USB_HID_REPORT_ID_KEYBOARD - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = keyboard_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_KEYBOARD, - .report_length = USB_HID_REPORT_LENGTH_KEYBOARD, - .usage_page = 0x01, - .usage = 0x06, - }, -#endif -#ifdef USB_HID_REPORT_ID_MOUSE - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = mouse_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_MOUSE, - .report_length = USB_HID_REPORT_LENGTH_MOUSE, - .usage_page = 0x01, - .usage = 0x02, - }, -#endif -#ifdef USB_HID_REPORT_ID_CONSUMER - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = consumer_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_CONSUMER, - .report_length = USB_HID_REPORT_LENGTH_CONSUMER, - .usage_page = 0x0C, - .usage = 0x01, - }, -#endif -#ifdef USB_HID_REPORT_ID_SYS_CONTROL - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = sys_control_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_SYS_CONTROL, - .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL, - .usage_page = 0x01, - .usage = 0x80, - }, -#endif -#ifdef USB_HID_REPORT_ID_GAMEPAD - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = gamepad_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_GAMEPAD, - .report_length = USB_HID_REPORT_LENGTH_GAMEPAD, - .usage_page = 0x01, - .usage = 0x05, - }, -#endif -#ifdef USB_HID_REPORT_ID_DIGITIZER - { - .base = { .type = &usb_hid_device_type }, - .report_buffer = digitizer_report_buffer, - .endpoint = USB_HID_ENDPOINT_IN, - .report_id = USB_HID_REPORT_ID_DIGITIZER, - .report_length = USB_HID_REPORT_LENGTH_DIGITIZER, - .usage_page = 0x0D, - .usage = 0x02, - }, -#endif -}; - - -mp_obj_tuple_t common_hal_usb_hid_devices = { - .base = { - .type = &mp_type_tuple, - }, - .len = USB_HID_NUM_DEVICES, - .items = { -#if USB_HID_NUM_DEVICES >= 1 - (mp_obj_t) &usb_hid_devices[0], -#endif -#if USB_HID_NUM_DEVICES >= 2 - (mp_obj_t) &usb_hid_devices[1], -#endif -#if USB_HID_NUM_DEVICES >= 3 - (mp_obj_t) &usb_hid_devices[2], -#endif -#if USB_HID_NUM_DEVICES >= 4 - (mp_obj_t) &usb_hid_devices[3], -#endif -#if USB_HID_NUM_DEVICES >= 5 - (mp_obj_t) &usb_hid_devices[4], -#endif -#if USB_HID_NUM_DEVICES >= 6 - (mp_obj_t) &usb_hid_devices[5], -#endif - } -}; diff --git a/ports/atmel-samd/external_flash/common_commands.h b/ports/atmel-samd/external_flash/common_commands.h deleted file mode 100644 index d82d2c046..000000000 --- a/ports/atmel-samd/external_flash/common_commands.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H - -#define CMD_READ_JEDEC_ID 0x9f -#define CMD_READ_DATA 0x03 -#define CMD_SECTOR_ERASE 0x20 -// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID -#define CMD_DISABLE_WRITE 0x04 -#define CMD_ENABLE_WRITE 0x06 -#define CMD_PAGE_PROGRAM 0x02 -// #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID -#define CMD_READ_STATUS 0x05 -#define CMD_READ_STATUS2 0x35 -#define CMD_WRITE_STATUS_BYTE1 0x01 -#define CMD_WRITE_STATUS_BYTE2 0x31 -#define CMD_DUAL_READ 0x3b -#define CMD_QUAD_READ 0x6b -#define CMD_ENABLE_RESET 0x66 -#define CMD_RESET 0x99 - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H diff --git a/ports/atmel-samd/external_flash/devices.h b/ports/atmel-samd/external_flash/devices.h deleted file mode 100644 index 58da2e509..000000000 --- a/ports/atmel-samd/external_flash/devices.h +++ /dev/null @@ -1,337 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H -#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H - -#include -#include - -typedef struct { - uint32_t total_size; - uint16_t start_up_time_us; - - // Three response bytes to 0x9f JEDEC ID command. - uint8_t manufacturer_id; - uint8_t memory_type; - uint8_t capacity; - - // Max clock speed for all operations and the fastest read mode. - uint8_t max_clock_speed_mhz; - bool has_sector_protection : 1; - - // Supports the 0x0b fast read command with 8 dummy cycles. - bool supports_fast_read : 1; - - // Supports the fast read, quad output command 0x6b with 8 dummy cycles. - bool supports_qspi : 1; - - // Requires quad enable set in status bit 9. - bool has_quad_enable : 1; - - // Supports the quad input page program command 0x32. This is known as 1-1-4 because it only - // uses all four lines for data. - bool supports_qspi_writes: 1; - - // Requires a separate command 0x31 to write to the second byte of the status register. - // Otherwise two byte are written via 0x01. - bool write_status_register_split: 1; -} external_flash_device; - -// Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. Its on the SAMD21 -// Xplained board. -// Datasheet: https://www.adestotech.com/wp-content/uploads/doc8715.pdf -#define AT25DF081A {\ - .total_size = (1 << 20), /* 1 MiB */ \ - .start_up_time_us = 10000, \ - .manufacturer_id = 0x1f, \ - .memory_type = 0x45, \ - .capacity = 0x01, \ - .max_clock_speed_mhz = 85, \ - .has_sector_protection = true, \ - .supports_fast_read = true, \ - .supports_qspi = false, \ - .has_quad_enable = false, \ - .supports_qspi_writes = false, \ - .write_status_register_split = false, \ -} - -// Settings for the Gigadevice GD25Q16C 2MiB SPI flash. -// Datasheet: http://www.gigadevice.com/wp-content/uploads/2017/12/DS-00086-GD25Q16C-Rev2.6.pdf -#define GD25Q16C {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xc8, \ - .memory_type = 0x40, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Gigadevice GD25Q64C 8MiB SPI flash. -// Datasheet: http://www.elm-tech.com/en/products/spi-flash-memory/gd25q64/gd25q64.pdf -#define GD25Q64C {\ - .total_size = (1 << 23), /* 8 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xc8, \ - .memory_type = 0x40, \ - .capacity = 0x17, \ - .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = true, \ -} - -// Settings for the Cypress (was Spansion) S25FL064L 8MiB SPI flash. -// Datasheet: http://www.cypress.com/file/316661/download -#define S25FL064L {\ - .total_size = (1 << 23), /* 8 MiB */ \ - .start_up_time_us = 300, \ - .manufacturer_id = 0x01, \ - .memory_type = 0x60, \ - .capacity = 0x17, \ - .max_clock_speed_mhz = 108, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Cypress (was Spansion) S25FL116K 2MiB SPI flash. -// Datasheet: http://www.cypress.com/file/196886/download -#define S25FL116K {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 10000, \ - .manufacturer_id = 0x01, \ - .memory_type = 0x40, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 108, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = false, \ - .write_status_register_split = false, \ -} - -// Settings for the Cypress (was Spansion) S25FL216K 2MiB SPI flash. -// Datasheet: http://www.cypress.com/file/197346/download -#define S25FL216K {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 10000, \ - .manufacturer_id = 0x01, \ - .memory_type = 0x40, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 65, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = false, \ - .has_quad_enable = false, \ - .supports_qspi_writes = false, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q16FW 2MiB SPI flash. -// Datasheet: https://www.winbond.com/resource-files/w25q16fw%20revj%2005182017%20sfdp.pdf -#define W25Q16FW {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x60, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) -// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf -#define W25Q16JV_IQ {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x40, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) -// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf -#define W25Q16JV_IM {\ - .total_size = (1 << 21), /* 2 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x70, \ - .capacity = 0x15, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q32BV 4MiB SPI flash. -// Datasheet: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf -#define W25Q32BV {\ - .total_size = (1 << 22), /* 4 MiB */ \ - .start_up_time_us = 10000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x60, \ - .capacity = 0x16, \ - .max_clock_speed_mhz = 104, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = false, \ - .write_status_register_split = false, \ -} -// Settings for the Winbond W25Q32JV-IM 4MiB SPI flash. -// Datasheet: https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf -#define W25Q32JV_IM {\ - .total_size = (1 << 22), /* 4 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x70, \ - .capacity = 0x16, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) -// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf -#define W25Q64JV_IM {\ - .total_size = (1 << 23), /* 8 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x70, \ - .capacity = 0x17, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) -// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf -#define W25Q64JV_IQ {\ - .total_size = (1 << 23), /* 8 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x40, \ - .capacity = 0x17, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -// Settings for the Winbond W25Q80DL 1MiB SPI flash. -// Datasheet: https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf -#define W25Q80DL {\ - .total_size = (1 << 20), /* 1 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x60, \ - .capacity = 0x14, \ - .max_clock_speed_mhz = 104, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = false, \ - .write_status_register_split = false, \ -} - - -// Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) -// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf -#define W25Q128JV_SQ {\ - .total_size = (1 << 24), /* 16 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x40, \ - .capacity = 0x18, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - - -// Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) -// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf -#define W25Q128JV_PM {\ - .total_size = (1 << 24), /* 16 MiB */ \ - .start_up_time_us = 5000, \ - .manufacturer_id = 0xef, \ - .memory_type = 0x70, \ - .capacity = 0x18, \ - .max_clock_speed_mhz = 133, \ - .has_sector_protection = false, \ - .supports_fast_read = true, \ - .supports_qspi = true, \ - .has_quad_enable = true, \ - .supports_qspi_writes = true, \ - .write_status_register_split = false, \ -} - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H diff --git a/ports/atmel-samd/external_flash/external_flash.c b/ports/atmel-samd/external_flash/external_flash.c deleted file mode 100644 index b4a637be4..000000000 --- a/ports/atmel-samd/external_flash/external_flash.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "external_flash.h" - -#include -#include - -#include "external_flash/spi_flash_api.h" -#include "external_flash/common_commands.h" -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "py/misc.h" -#include "py/obj.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "supervisor/memory.h" -#include "supervisor/shared/rgb_led_status.h" - -#include "hal_gpio.h" -#include "hal_spi_m_sync.h" - -#define SPI_FLASH_PART1_START_BLOCK (0x1) - -#define NO_SECTOR_LOADED 0xFFFFFFFF - -struct spi_m_sync_descriptor spi_flash_desc; - -// The currently cached sector in the cache, ram or flash based. -static uint32_t current_sector; - -const external_flash_device possible_devices[EXTERNAL_FLASH_DEVICE_COUNT] = {EXTERNAL_FLASH_DEVICES}; - -static const external_flash_device* flash_device = NULL; - -// Track which blocks (up to 32) in the current sector currently live in the -// cache. -static uint32_t dirty_mask; - -static supervisor_allocation* supervisor_cache = NULL; - -// Wait until both the write enable and write in progress bits have cleared. -static bool wait_for_flash_ready(void) { - uint8_t read_status_response[1] = {0x00}; - bool ok = true; - // Both the write enable and write in progress bits should be low. - do { - ok = spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); - } while (ok && (read_status_response[0] & 0x3) != 0); - return ok; -} - -// Turn on the write enable bit so we can program and erase the flash. -static bool write_enable(void) { - return spi_flash_command(CMD_ENABLE_WRITE); -} - -// Read data_length's worth of bytes starting at address into data. -static bool read_flash(uint32_t address, uint8_t* data, uint32_t data_length) { - if (flash_device == NULL) { - return false; - } - if (!wait_for_flash_ready()) { - return false; - } - return spi_flash_read_data(address, data, data_length); -} - -// Writes data_length's worth of bytes starting at address from data. Assumes -// that the sector that address resides in has already been erased. So make sure -// to run erase_sector. -static bool write_flash(uint32_t address, const uint8_t* data, uint32_t data_length) { - if (flash_device == NULL) { - return false; - } - // Don't bother writing if the data is all 1s. Thats equivalent to the flash - // state after an erase. - bool all_ones = true; - for (uint16_t i = 0; i < data_length; i++) { - if (data[i] != 0xff) { - all_ones = false; - break; - } - } - if (all_ones) { - return true; - } - - for (uint32_t bytes_written = 0; - bytes_written < data_length; - bytes_written += SPI_FLASH_PAGE_SIZE) { - if (!wait_for_flash_ready() || !write_enable()) { - return false; - } - - if (!spi_flash_write_data(address + bytes_written, (uint8_t*) data + bytes_written, - SPI_FLASH_PAGE_SIZE)) { - return false; - } - } - return true; -} - -static bool page_erased(uint32_t sector_address) { - // Check the first few bytes to catch the common case where there is data - // without using a bunch of memory. - uint8_t short_buffer[4]; - if (read_flash(sector_address, short_buffer, 4)) { - for (uint16_t i = 0; i < 4; i++) { - if (short_buffer[i] != 0xff) { - return false; - } - } - } else { - return false; - } - - // Now check the full length. - uint8_t full_buffer[FILESYSTEM_BLOCK_SIZE]; - if (read_flash(sector_address, full_buffer, FILESYSTEM_BLOCK_SIZE)) { - for (uint16_t i = 0; i < FILESYSTEM_BLOCK_SIZE; i++) { - if (short_buffer[i] != 0xff) { - return false; - } - } - } else { - return false; - } - return true; -} - -// Erases the given sector. Make sure you copied all of the data out of it you -// need! Also note, sector_address is really 24 bits. -static bool erase_sector(uint32_t sector_address) { - // Before we erase the sector we need to wait for any writes to finish and - // and then enable the write again. - if (!wait_for_flash_ready() || !write_enable()) { - return false; - } - - spi_flash_sector_command(CMD_SECTOR_ERASE, sector_address); - return true; -} - -// Sector is really 24 bits. -static bool copy_block(uint32_t src_address, uint32_t dest_address) { - // Copy page by page to minimize RAM buffer. - uint16_t page_size = SPI_FLASH_PAGE_SIZE; - uint8_t buffer[page_size]; - for (uint32_t i = 0; i < FILESYSTEM_BLOCK_SIZE / page_size; i++) { - if (!read_flash(src_address + i * page_size, buffer, page_size)) { - return false; - } - if (!write_flash(dest_address + i * page_size, buffer, page_size)) { - return false; - } - } - return true; -} - -void external_flash_init(void) { - if (flash_device != NULL) { - return; - } - - // Delay to give the SPI Flash time to get going. - // TODO(tannewt): Only do this when we know power was applied vs a reset. - uint16_t max_start_up_delay_us = 0; - for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { - if (possible_devices[i].start_up_time_us > max_start_up_delay_us) { - max_start_up_delay_us = possible_devices[i].start_up_time_us; - } - } - common_hal_mcu_delay_us(max_start_up_delay_us); - - spi_flash_init(); - - // The response will be 0xff if the flash needs more time to start up. - uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff}; - while (jedec_id_response[0] == 0xff) { - spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); - } - - for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { - const external_flash_device* possible_device = &possible_devices[i]; - if (jedec_id_response[0] == possible_device->manufacturer_id && - jedec_id_response[1] == possible_device->memory_type && - jedec_id_response[2] == possible_device->capacity) { - flash_device = possible_device; - break; - } - } - - if (flash_device == NULL) { - return; - } - - // We don't know what state the flash is in so wait for any remaining writes and then reset. - uint8_t read_status_response[1] = {0x00}; - // The write in progress bit should be low. - do { - spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); - } while ((read_status_response[0] & 0x1) != 0); - // The suspended write/erase bit should be low. - do { - spi_flash_read_command(CMD_READ_STATUS2, read_status_response, 1); - } while ((read_status_response[0] & 0x80) != 0); - - - spi_flash_command(CMD_ENABLE_RESET); - spi_flash_command(CMD_RESET); - - // Wait 30us for the reset - common_hal_mcu_delay_us(30); - - spi_flash_init_device(flash_device); - - // Activity LED for flash writes. -#ifdef MICROPY_HW_LED_MSC - gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_MSC, GPIO_DIRECTION_OUT); - // There's already a pull-up on the board. - gpio_set_pin_level(MICROPY_HW_LED_MSC, false); -#endif - - if (flash_device->has_sector_protection) { - write_enable(); - - // Turn off sector protection - uint8_t data[1] = {0x00}; - spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1); - } - - // Turn off writes in case this is a microcontroller only reset. - spi_flash_command(CMD_DISABLE_WRITE); - - wait_for_flash_ready(); - - current_sector = NO_SECTOR_LOADED; - dirty_mask = 0; - MP_STATE_VM(flash_ram_cache) = NULL; -} - -// The size of each individual block. -uint32_t external_flash_get_block_size(void) { - return FILESYSTEM_BLOCK_SIZE; -} - -// The total number of available blocks. -uint32_t external_flash_get_block_count(void) { - // We subtract one erase sector size because we may use it as a staging area - // for writes. - return SPI_FLASH_PART1_START_BLOCK + (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; -} - -// Flush the cache that was written to the scratch portion of flash. Only used -// when ram is tight. -static bool flush_scratch_flash(void) { - // First, copy out any blocks that we haven't touched from the sector we've - // cached. - bool copy_to_scratch_ok = true; - uint32_t scratch_sector = flash_device->total_size - SPI_FLASH_ERASE_SIZE; - for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { - if ((dirty_mask & (1 << i)) == 0) { - copy_to_scratch_ok = copy_to_scratch_ok && - copy_block(current_sector + i * FILESYSTEM_BLOCK_SIZE, - scratch_sector + i * FILESYSTEM_BLOCK_SIZE); - } - } - if (!copy_to_scratch_ok) { - // TODO(tannewt): Do more here. We opted to not erase and copy bad data - // in. We still risk losing the data written to the scratch sector. - return false; - } - // Second, erase the current sector. - erase_sector(current_sector); - // Finally, copy the new version into it. - for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { - copy_block(scratch_sector + i * FILESYSTEM_BLOCK_SIZE, - current_sector + i * FILESYSTEM_BLOCK_SIZE); - } - return true; -} - -// Attempts to allocate a new set of page buffers for caching a full sector in -// ram. Each page is allocated separately so that the GC doesn't need to provide -// one huge block. We can free it as we write if we want to also. -static bool allocate_ram_cache(void) { - uint8_t blocks_per_sector = SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; - uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; - - uint32_t table_size = blocks_per_sector * pages_per_block * sizeof(uint32_t); - // Attempt to allocate outside the heap first. - supervisor_cache = allocate_memory(table_size + SPI_FLASH_ERASE_SIZE, false); - if (supervisor_cache != NULL) { - MP_STATE_VM(flash_ram_cache) = (uint8_t **) supervisor_cache->ptr; - uint8_t* page_start = (uint8_t *) supervisor_cache->ptr + table_size; - - for (uint8_t i = 0; i < blocks_per_sector; i++) { - for (uint8_t j = 0; j < pages_per_block; j++) { - uint32_t offset = i * pages_per_block + j; - MP_STATE_VM(flash_ram_cache)[offset] = page_start + offset * SPI_FLASH_PAGE_SIZE; - } - } - return true; - } - - MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t), false); - if (MP_STATE_VM(flash_ram_cache) == NULL) { - return false; - } - // Declare i and j outside the loops in case we fail to allocate everything - // we need. In that case we'll give it back. - uint8_t i = 0; - uint8_t j = 0; - bool success = true; - for (i = 0; i < blocks_per_sector; i++) { - for (j = 0; j < pages_per_block; j++) { - uint8_t *page_cache = m_malloc_maybe(SPI_FLASH_PAGE_SIZE, false); - if (page_cache == NULL) { - success = false; - break; - } - MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j] = page_cache; - } - if (!success) { - break; - } - } - // We couldn't allocate enough so give back what we got. - if (!success) { - // We add 1 so that we delete 0 when i is 1. Going to zero (i >= 0) - // would never stop because i is unsigned. - i++; - for (; i > 0; i--) { - for (; j > 0; j--) { - m_free(MP_STATE_VM(flash_ram_cache)[(i - 1) * pages_per_block + (j - 1)]); - } - j = pages_per_block; - } - m_free(MP_STATE_VM(flash_ram_cache)); - MP_STATE_VM(flash_ram_cache) = NULL; - } - return success; -} - -// Flush the cached sector from ram onto the flash. We'll free the cache unless -// keep_cache is true. -static bool flush_ram_cache(bool keep_cache) { - // First, copy out any blocks that we haven't touched from the sector - // we've cached. If we don't do this we'll erase the data during the sector - // erase below. - bool copy_to_ram_ok = true; - uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; - for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { - if ((dirty_mask & (1 << i)) == 0) { - for (uint8_t j = 0; j < pages_per_block; j++) { - copy_to_ram_ok = read_flash( - current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, - MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], - SPI_FLASH_PAGE_SIZE); - if (!copy_to_ram_ok) { - break; - } - } - } - if (!copy_to_ram_ok) { - break; - } - } - - if (!copy_to_ram_ok) { - return false; - } - // Second, erase the current sector. - erase_sector(current_sector); - // Lastly, write all the data in ram that we've cached. - for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { - for (uint8_t j = 0; j < pages_per_block; j++) { - write_flash(current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, - MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], - SPI_FLASH_PAGE_SIZE); - if (!keep_cache && supervisor_cache == NULL) { - m_free(MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j]); - } - } - } - // We're done with the cache for now so give it back. - if (!keep_cache) { - if (supervisor_cache != NULL) { - free_memory(supervisor_cache); - supervisor_cache = NULL; - } else { - m_free(MP_STATE_VM(flash_ram_cache)); - } - MP_STATE_VM(flash_ram_cache) = NULL; - } - return true; -} - -// Delegates to the correct flash flush method depending on the existing cache. -static void spi_flash_flush_keep_cache(bool keep_cache) { - if (current_sector == NO_SECTOR_LOADED) { - return; - } - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, true); - #endif - temp_status_color(ACTIVE_WRITE); - // If we've cached to the flash itself flush from there. - if (MP_STATE_VM(flash_ram_cache) == NULL) { - flush_scratch_flash(); - } else { - flush_ram_cache(keep_cache); - } - current_sector = NO_SECTOR_LOADED; - clear_temp_status(); - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); - #endif -} - -// External flash function used. If called externally we assume we won't need -// the cache after. -void external_flash_flush(void) { - spi_flash_flush_keep_cache(false); -} - -void flash_flush(void) { - external_flash_flush(); -} - -// Builds a partition entry for the MBR. -static void build_partition(uint8_t *buf, int boot, int type, - uint32_t start_block, uint32_t num_blocks) { - buf[0] = boot; - - if (num_blocks == 0) { - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - } else { - buf[1] = 0xff; - buf[2] = 0xff; - buf[3] = 0xff; - } - - buf[4] = type; - - if (num_blocks == 0) { - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - } else { - buf[5] = 0xff; - buf[6] = 0xff; - buf[7] = 0xff; - } - - buf[8] = start_block; - buf[9] = start_block >> 8; - buf[10] = start_block >> 16; - buf[11] = start_block >> 24; - - buf[12] = num_blocks; - buf[13] = num_blocks >> 8; - buf[14] = num_blocks >> 16; - buf[15] = num_blocks >> 24; -} - -static int32_t convert_block_to_flash_addr(uint32_t block) { - if (SPI_FLASH_PART1_START_BLOCK <= block && block < external_flash_get_block_count()) { - // a block in partition 1 - block -= SPI_FLASH_PART1_START_BLOCK; - return block * FILESYSTEM_BLOCK_SIZE; - } - // bad block - return -1; -} - -bool external_flash_read_block(uint8_t *dest, uint32_t block) { - if (block == 0) { - // Fake the MBR so we can decide on our own partition table - for (int i = 0; i < 446; i++) { - dest[i] = 0; - } - - build_partition(dest + 446, 0, 0x01 /* FAT12 */, - SPI_FLASH_PART1_START_BLOCK, - external_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK); - build_partition(dest + 462, 0, 0, 0, 0); - build_partition(dest + 478, 0, 0, 0, 0); - build_partition(dest + 494, 0, 0, 0, 0); - - dest[510] = 0x55; - dest[511] = 0xaa; - - return true; - } else if (block < SPI_FLASH_PART1_START_BLOCK) { - memset(dest, 0, FILESYSTEM_BLOCK_SIZE); - return true; - } else { - // Non-MBR block, get data from flash memory. - int32_t address = convert_block_to_flash_addr(block); - if (address == -1) { - // bad block number - return false; - } - - // Mask out the lower bits that designate the address within the sector. - uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); - uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); - uint8_t mask = 1 << (block_index); - // We're reading from the currently cached sector. - if (current_sector == this_sector && (mask & dirty_mask) > 0) { - if (MP_STATE_VM(flash_ram_cache) != NULL) { - uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; - for (int i = 0; i < pages_per_block; i++) { - memcpy(dest + i * SPI_FLASH_PAGE_SIZE, - MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], - SPI_FLASH_PAGE_SIZE); - } - return true; - } else { - uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; - return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE); - } - } - return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); - } -} - -bool external_flash_write_block(const uint8_t *data, uint32_t block) { - if (block < SPI_FLASH_PART1_START_BLOCK) { - // Fake writing below the flash partition. - return true; - } else { - // Non-MBR block, copy to cache - int32_t address = convert_block_to_flash_addr(block); - if (address == -1) { - // bad block number - return false; - } - // Wait for any previous writes to finish. - wait_for_flash_ready(); - // Mask out the lower bits that designate the address within the sector. - uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); - uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); - uint8_t mask = 1 << (block_index); - // Flush the cache if we're moving onto a sector or we're writing the - // same block again. - if (current_sector != this_sector || (mask & dirty_mask) > 0) { - // Check to see if we'd write to an erased page. In that case we - // can write directly. - if (page_erased(address)) { - return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); - } - if (current_sector != NO_SECTOR_LOADED) { - spi_flash_flush_keep_cache(true); - } - if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) { - erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE); - wait_for_flash_ready(); - } - current_sector = this_sector; - dirty_mask = 0; - } - dirty_mask |= mask; - // Copy the block to the appropriate cache. - if (MP_STATE_VM(flash_ram_cache) != NULL) { - uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; - for (int i = 0; i < pages_per_block; i++) { - memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], - data + i * SPI_FLASH_PAGE_SIZE, - SPI_FLASH_PAGE_SIZE); - } - return true; - } else { - uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; - return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE); - } - } -} - -mp_uint_t external_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { - for (size_t i = 0; i < num_blocks; i++) { - if (!external_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { - return 1; // error - } - } - return 0; // success -} - -mp_uint_t external_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { - for (size_t i = 0; i < num_blocks; i++) { - if (!external_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { - return 1; // error - } - } - return 0; // success -} - -/******************************************************************************/ -// MicroPython bindings -// -// Expose the flash as an object with the block protocol. - -// there is a singleton Flash object -STATIC const mp_obj_base_t external_flash_obj = {&external_flash_type}; - -STATIC mp_obj_t external_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); - - // return singleton object - return (mp_obj_t)&external_flash_obj; -} - -STATIC mp_obj_t external_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); - mp_uint_t ret = external_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_readblocks_obj, external_flash_obj_readblocks); - -STATIC mp_obj_t external_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - mp_uint_t ret = external_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_writeblocks_obj, external_flash_obj_writeblocks); - -STATIC mp_obj_t external_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { - mp_int_t cmd = mp_obj_get_int(cmd_in); - switch (cmd) { - case BP_IOCTL_INIT: external_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_DEINIT: external_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly - case BP_IOCTL_SYNC: external_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(external_flash_get_block_count()); - case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(external_flash_get_block_size()); - default: return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(external_flash_obj_ioctl_obj, external_flash_obj_ioctl); - -STATIC const mp_rom_map_elem_t external_flash_obj_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&external_flash_obj_readblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&external_flash_obj_writeblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&external_flash_obj_ioctl_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(external_flash_obj_locals_dict, external_flash_obj_locals_dict_table); - -const mp_obj_type_t external_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_SPIFlash, - .make_new = external_flash_obj_make_new, - .locals_dict = (mp_obj_t)&external_flash_obj_locals_dict, -}; - -void flash_init_vfs(fs_user_mount_t *vfs) { - vfs->base.type = &mp_fat_vfs_type; - vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; - vfs->fatfs.drv = vfs; - vfs->fatfs.part = 1; // flash filesystem lives on first partition - vfs->readblocks[0] = (mp_obj_t)&external_flash_obj_readblocks_obj; - vfs->readblocks[1] = (mp_obj_t)&external_flash_obj; - vfs->readblocks[2] = (mp_obj_t)external_flash_read_blocks; // native version - vfs->writeblocks[0] = (mp_obj_t)&external_flash_obj_writeblocks_obj; - vfs->writeblocks[1] = (mp_obj_t)&external_flash_obj; - vfs->writeblocks[2] = (mp_obj_t)external_flash_write_blocks; // native version - vfs->u.ioctl[0] = (mp_obj_t)&external_flash_obj_ioctl_obj; - vfs->u.ioctl[1] = (mp_obj_t)&external_flash_obj; -} diff --git a/ports/atmel-samd/external_flash/external_flash.h b/ports/atmel-samd/external_flash/external_flash.h deleted file mode 100644 index f8ec5673c..000000000 --- a/ports/atmel-samd/external_flash/external_flash.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H -#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H - -#include - -#include "mpconfigport.h" - -// We use this when we can allocate the whole cache in RAM. -#define FLASH_ROOT_POINTERS \ - uint8_t** flash_ram_cache; \ - -// Erase sector size. -#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100) - -// These are common across all NOR Flash. -#define SPI_FLASH_ERASE_SIZE (1 << 12) -#define SPI_FLASH_PAGE_SIZE (256) - -#define SPI_FLASH_SYSTICK_MASK (0x1ff) // 512ms -#define SPI_FLASH_IDLE_TICK(tick) (((tick) & SPI_FLASH_SYSTICK_MASK) == 2) - -void external_flash_init(void); -uint32_t external_flash_get_block_size(void); -uint32_t external_flash_get_block_count(void); -void external_flash_irq_handler(void); -void external_flash_flush(void); -bool external_flash_read_block(uint8_t *dest, uint32_t block); -bool external_flash_write_block(const uint8_t *src, uint32_t block); - -// these return 0 on success, non-zero on error -mp_uint_t external_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -mp_uint_t external_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); - -extern const struct _mp_obj_type_t external_flash_type; - -struct _fs_user_mount_t; -void flash_init_vfs(struct _fs_user_mount_t *vfs); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_H diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/external_flash/qspi_flash.c deleted file mode 100644 index f6dc00d50..000000000 --- a/ports/atmel-samd/external_flash/qspi_flash.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "spi_flash_api.h" - -#include -#include - -#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL - -#include "external_flash/common_commands.h" -#include "samd/cache.h" -#include "samd/dma.h" - -#include "atmel_start_pins.h" -#include "hal_gpio.h" - -bool spi_flash_command(uint8_t command) { - QSPI->INSTRCTRL.bit.INSTR = command; - - QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_READ | - QSPI_INSTRFRAME_INSTREN; - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - return true; -} - -bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { - samd_peripherals_disable_and_clear_cache(); - - QSPI->INSTRCTRL.bit.INSTR = command; - - QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_READ | - QSPI_INSTRFRAME_INSTREN | - QSPI_INSTRFRAME_DATAEN; - - // Dummy read of INSTRFRAME needed to synchronize. - // See Instruction Transmission Flow Diagram, figure 37.9, page 995 - // and Example 4, page 998, section 37.6.8.5. - (volatile uint32_t) QSPI->INSTRFRAME.reg; - - memcpy(response, (uint8_t *) QSPI_AHB, length); - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - samd_peripherals_enable_cache(); - - return true; -} - -bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { - samd_peripherals_disable_and_clear_cache(); - - QSPI->INSTRCTRL.bit.INSTR = command; - - QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_WRITE | - QSPI_INSTRFRAME_INSTREN | - (data != NULL ? QSPI_INSTRFRAME_DATAEN : 0); - - // Dummy read of INSTRFRAME needed to synchronize. - // See Instruction Transmission Flow Diagram, figure 37.9, page 995 - // and Example 4, page 998, section 37.6.8.5. - (volatile uint32_t) QSPI->INSTRFRAME.reg; - - if (data != NULL) { - memcpy((uint8_t *) QSPI_AHB, data, length); - } - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - samd_peripherals_enable_cache(); - - return true; -} - -bool spi_flash_sector_command(uint8_t command, uint32_t address) { - QSPI->INSTRCTRL.bit.INSTR = command; - QSPI->INSTRADDR.bit.ADDR = address; - - QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_WRITE | - QSPI_INSTRFRAME_INSTREN | - QSPI_INSTRFRAME_ADDREN; - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - return true; -} - -bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { - samd_peripherals_disable_and_clear_cache(); - - QSPI->INSTRCTRL.bit.INSTR = CMD_PAGE_PROGRAM; - uint32_t mode = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI; - - QSPI->INSTRFRAME.reg = mode | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_WRITEMEMORY | - QSPI_INSTRFRAME_INSTREN | - QSPI_INSTRFRAME_ADDREN | - QSPI_INSTRFRAME_DATAEN; - - memcpy(((uint8_t *) QSPI_AHB) + address, data, length); - // TODO(tannewt): Fix DMA and enable it. - // qspi_dma_write(address, data, length); - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - samd_peripherals_enable_cache(); - - return true; -} - -bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { - samd_peripherals_disable_and_clear_cache(); - - #ifdef EXTERNAL_FLASH_QSPI_DUAL - QSPI->INSTRCTRL.bit.INSTR = CMD_DUAL_READ; - uint32_t mode = QSPI_INSTRFRAME_WIDTH_DUAL_OUTPUT; - #else - QSPI->INSTRCTRL.bit.INSTR = CMD_QUAD_READ; - uint32_t mode = QSPI_INSTRFRAME_WIDTH_QUAD_OUTPUT; - #endif - - QSPI->INSTRFRAME.reg = mode | - QSPI_INSTRFRAME_ADDRLEN_24BITS | - QSPI_INSTRFRAME_TFRTYPE_READMEMORY | - QSPI_INSTRFRAME_INSTREN | - QSPI_INSTRFRAME_ADDREN | - QSPI_INSTRFRAME_DATAEN | - QSPI_INSTRFRAME_DUMMYLEN(8); - - memcpy(data, ((uint8_t *) QSPI_AHB) + address, length); - // TODO(tannewt): Fix DMA and enable it. - // qspi_dma_read(address, data, length); - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; - - while( !QSPI->INTFLAG.bit.INSTREND ); - - QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; - - samd_peripherals_enable_cache(); - - return true; -} - - -void spi_flash_init(void) { - MCLK->APBCMASK.bit.QSPI_ = true; - MCLK->AHBMASK.bit.QSPI_ = true; - MCLK->AHBMASK.bit.QSPI_2X_ = false; // Only true if we are doing DDR. - - QSPI->CTRLA.reg = QSPI_CTRLA_SWRST; - // We don't need to wait because we're running as fast as the CPU. - - // Slow, good for debugging with Saleae - // QSPI->BAUD.bit.BAUD = 32; - // Super fast, may be unreliable when Saleae is connected to high speed lines. - QSPI->BAUD.bit.BAUD = 2; - QSPI->CTRLB.reg = QSPI_CTRLB_MODE_MEMORY | // Serial memory mode (map to QSPI_AHB) - QSPI_CTRLB_DATALEN_8BITS | - QSPI_CTRLB_CSMODE_LASTXFER; - - QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE; - - // The QSPI is only connected to one set of pins in the SAMD51 so we can hard code it. - uint32_t pins[6] = {PIN_PA08, PIN_PA09, PIN_PA10, PIN_PA11, PIN_PB10, PIN_PB11}; - for (uint8_t i = 0; i < 6; i++) { - gpio_set_pin_direction(pins[i], GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(pins[i], GPIO_PULL_OFF); - gpio_set_pin_function(pins[i], GPIO_PIN_FUNCTION_H); - } -} - -void spi_flash_init_device(const external_flash_device* device) { - // Verify that QSPI mode is enabled. - uint8_t status; - spi_flash_read_command(CMD_READ_STATUS2, &status, 1); - - // Bit 1 is Quad Enable - if ((status & 0x2) == 0) { - uint8_t full_status[2] = {0x0, 0x2}; - spi_flash_command(CMD_ENABLE_WRITE); - if (device->write_status_register_split) { - spi_flash_write_command(CMD_WRITE_STATUS_BYTE2, full_status + 1, 1); - } else { - spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2); - } - } -} diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/ports/atmel-samd/external_flash/spi_flash.c deleted file mode 100644 index 273915df7..000000000 --- a/ports/atmel-samd/external_flash/spi_flash.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "spi_flash_api.h" - -#include -#include - -#include "external_flash/common_commands.h" -#include "samd/sercom.h" -#include "py/mpconfig.h" - -#include "hal_gpio.h" -#include "hal_spi_m_sync.h" - -struct spi_m_sync_descriptor spi_flash_desc; - -// Enable the flash over SPI. -static void flash_enable(void) { - gpio_set_pin_level(SPI_FLASH_CS_PIN, false); -} - -// Disable the flash over SPI. -static void flash_disable(void) { - gpio_set_pin_level(SPI_FLASH_CS_PIN, true); -} - -static bool transfer(uint8_t* command, uint32_t command_length, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { - struct spi_xfer xfer = { command, NULL, command_length }; - flash_enable(); - int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer); - if (status >= 0 && !(data_in == NULL && data_out == NULL)) { - struct spi_xfer data_xfer = {data_in, data_out, data_length}; - status = spi_m_sync_transfer(&spi_flash_desc, &data_xfer); - } - flash_disable(); - return status >= 0; -} - -static bool transfer_command(uint8_t command, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { - return transfer(&command, 1, data_in, data_out, data_length); -} - -bool spi_flash_command(uint8_t command) { - return transfer_command(command, NULL, NULL, 0); -} - -bool spi_flash_read_command(uint8_t command, uint8_t* data, uint32_t data_length) { - return transfer_command(command, NULL, data, data_length); -} - -bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t data_length) { - return transfer_command(command, data, NULL, data_length); -} - -// Pack the low 24 bits of the address into a uint8_t array. -static void address_to_bytes(uint32_t address, uint8_t* bytes) { - bytes[0] = (address >> 16) & 0xff; - bytes[1] = (address >> 8) & 0xff; - bytes[2] = address & 0xff; -} - -bool spi_flash_sector_command(uint8_t command, uint32_t address) { - uint8_t request[4] = {command, 0x00, 0x00, 0x00}; - address_to_bytes(address, request + 1); - return transfer(request, 4, NULL, NULL, 0); -} - -bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length) { - uint8_t request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00}; - // Write the SPI flash write address into the bytes following the command byte. - address_to_bytes(address, request + 1); - struct spi_xfer xfer = { request, NULL, 4 }; - flash_enable(); - int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer); - if (status >= 0) { - status = sercom_dma_write(spi_flash_desc.dev.prvt, data, data_length); - } - flash_disable(); - return status >= 0; -} - -bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) { - uint8_t request[4] = {CMD_READ_DATA, 0x00, 0x00, 0x00}; - // Write the SPI flash write address into the bytes following the command byte. - address_to_bytes(address, request + 1); - struct spi_xfer xfer = { request, NULL, 4 }; - flash_enable(); - int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer); - if (status >= 0) { - status = sercom_dma_read(spi_flash_desc.dev.prvt, data, data_length, 0xff); - } - flash_disable(); - return status >= 0; -} - -void spi_flash_init(void) { - samd_peripherals_sercom_clock_init(SPI_FLASH_SERCOM, SPI_FLASH_SERCOM_INDEX); - - // Set up with defaults, then change. - spi_m_sync_init(&spi_flash_desc, SPI_FLASH_SERCOM); - - hri_sercomspi_write_CTRLA_DOPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DOPO); - hri_sercomspi_write_CTRLA_DIPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DIPO); - - gpio_set_pin_direction(SPI_FLASH_SCK_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(SPI_FLASH_SCK_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(SPI_FLASH_SCK_PIN, SPI_FLASH_SCK_PIN_FUNCTION); - - gpio_set_pin_direction(SPI_FLASH_MOSI_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(SPI_FLASH_MOSI_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(SPI_FLASH_MOSI_PIN, SPI_FLASH_MOSI_PIN_FUNCTION); - - gpio_set_pin_direction(SPI_FLASH_MISO_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(SPI_FLASH_MISO_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(SPI_FLASH_MISO_PIN, SPI_FLASH_MISO_PIN_FUNCTION); - - hri_sercomspi_write_CTRLA_DOPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DOPO); - hri_sercomspi_write_CTRLA_DIPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DIPO); - - spi_m_sync_set_baudrate(&spi_flash_desc, samd_peripherals_spi_baudrate_to_baud_reg_value(SPI_FLASH_BAUDRATE)); - - gpio_set_pin_direction(SPI_FLASH_CS_PIN, GPIO_DIRECTION_OUT); - // There's already a pull-up on the board. - gpio_set_pin_pull_mode(SPI_FLASH_CS_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF); - - // Set CS high (disabled). - flash_disable(); - - spi_m_sync_enable(&spi_flash_desc); -} - -void spi_flash_init_device(const external_flash_device* device) { - -} diff --git a/ports/atmel-samd/external_flash/spi_flash_api.h b/ports/atmel-samd/external_flash/spi_flash_api.h deleted file mode 100644 index a6df0c459..000000000 --- a/ports/atmel-samd/external_flash/spi_flash_api.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H - -#include -#include - -#include "external_flash/devices.h" - -// This API is implemented for both normal SPI peripherals and QSPI peripherals. - -bool spi_flash_command(uint8_t command); -bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length); -bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length); -bool spi_flash_sector_command(uint8_t command, uint32_t address); -bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length); -bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length); -void spi_flash_init(void); -void spi_flash_init_device(const external_flash_device* device); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H diff --git a/ports/atmel-samd/flash_api.c b/ports/atmel-samd/flash_api.c deleted file mode 100644 index b8a212718..000000000 --- a/ports/atmel-samd/flash_api.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "flash_api.h" - -#include "py/mpstate.h" - -#define VFS_INDEX 0 - -void flash_set_usb_writable(bool usb_writable) { - mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); - for (uint8_t i = 0; current_mount != NULL; i++) { - if (i == VFS_INDEX) { - break; - } - current_mount = current_mount->next; - } - if (current_mount == NULL) { - return; - } - fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj; - - if (usb_writable) { - vfs->flags |= FSUSER_USB_WRITABLE; - } else { - vfs->flags &= ~FSUSER_USB_WRITABLE; - } -} diff --git a/ports/atmel-samd/flash_api.h b/ports/atmel-samd/flash_api.h deleted file mode 100644 index 3e41f59a2..000000000 --- a/ports/atmel-samd/flash_api.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H -#define MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H - -#include "extmod/vfs_fat.h" - -extern void flash_init_vfs(fs_user_mount_t *vfs); -extern void flash_flush(void); - -void flash_set_usb_writable(bool usb_writable); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H diff --git a/ports/atmel-samd/internal_flash.c b/ports/atmel-samd/internal_flash.c deleted file mode 100644 index 35eb52da2..000000000 --- a/ports/atmel-samd/internal_flash.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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 "internal_flash.h" - -#include -#include - -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "py/mphal.h" -#include "py/obj.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" - -#ifdef SAMD21 -#include "hpl/pm/hpl_pm_base.h" -#endif -#include "hal/include/hal_flash.h" - -#include "supervisor/shared/rgb_led_status.h" - -static struct flash_descriptor internal_flash_desc; - -void internal_flash_init(void) { - // Activity LED for flash writes. - #ifdef MICROPY_HW_LED_MSC - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_OUTPUT; - port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf); - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); - #endif - - #ifdef SAMD51 - hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK); - #endif - #ifdef SAMD21 - _pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL); - #endif - flash_init(&internal_flash_desc, NVMCTRL); -} - -uint32_t internal_flash_get_block_size(void) { - return FILESYSTEM_BLOCK_SIZE; -} - -uint32_t internal_flash_get_block_count(void) { - return INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS; -} - -void internal_flash_flush(void) { -} - -void flash_flush(void) { - internal_flash_flush(); -} - -static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { - buf[0] = boot; - - if (num_blocks == 0) { - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - } else { - buf[1] = 0xff; - buf[2] = 0xff; - buf[3] = 0xff; - } - - buf[4] = type; - - if (num_blocks == 0) { - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - } else { - buf[5] = 0xff; - buf[6] = 0xff; - buf[7] = 0xff; - } - - buf[8] = start_block; - buf[9] = start_block >> 8; - buf[10] = start_block >> 16; - buf[11] = start_block >> 24; - - buf[12] = num_blocks; - buf[13] = num_blocks >> 8; - buf[14] = num_blocks >> 16; - buf[15] = num_blocks >> 24; -} - -static int32_t convert_block_to_flash_addr(uint32_t block) { - if (INTERNAL_FLASH_PART1_START_BLOCK <= block && block < INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS) { - // a block in partition 1 - block -= INTERNAL_FLASH_PART1_START_BLOCK; - return INTERNAL_FLASH_MEM_SEG1_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; - } - // bad block - return -1; -} - -bool internal_flash_read_block(uint8_t *dest, uint32_t block) { - if (block == 0) { - // fake the MBR so we can decide on our own partition table - - for (int i = 0; i < 446; i++) { - dest[i] = 0; - } - - build_partition(dest + 446, 0, 0x01 /* FAT12 */, INTERNAL_FLASH_PART1_START_BLOCK, INTERNAL_FLASH_PART1_NUM_BLOCKS); - build_partition(dest + 462, 0, 0, 0, 0); - build_partition(dest + 478, 0, 0, 0, 0); - build_partition(dest + 494, 0, 0, 0, 0); - - dest[510] = 0x55; - dest[511] = 0xaa; - - return true; - - } else { - // non-MBR block, get data from flash memory - int32_t src = convert_block_to_flash_addr(block); - if (src == -1) { - // bad block number - return false; - } - int32_t error_code = flash_read(&internal_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE); - return error_code == ERR_NONE; - } -} - -bool internal_flash_write_block(const uint8_t *src, uint32_t block) { - if (block == 0) { - // can't write MBR, but pretend we did - return true; - - } else { - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, true); - #endif - temp_status_color(ACTIVE_WRITE); - // non-MBR block, copy to cache - int32_t dest = convert_block_to_flash_addr(block); - if (dest == -1) { - // bad block number - return false; - } - int32_t error_code; - error_code = flash_erase(&internal_flash_desc, - dest, - FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&internal_flash_desc)); - if (error_code != ERR_NONE) { - return false; - } - - error_code = flash_append(&internal_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE); - if (error_code != ERR_NONE) { - return false; - } - clear_temp_status(); - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); - #endif - return true; - } -} - -mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { - for (size_t i = 0; i < num_blocks; i++) { - if (!internal_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { - return 1; // error - } - } - return 0; // success -} - -mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { - for (size_t i = 0; i < num_blocks; i++) { - if (!internal_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { - return 1; // error - } - } - return 0; // success -} - -/******************************************************************************/ -// MicroPython bindings -// -// Expose the flash as an object with the block protocol. - -// there is a singleton Flash object -STATIC const mp_obj_base_t internal_flash_obj = {&internal_flash_type}; - -STATIC mp_obj_t internal_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); - - // return singleton object - return (mp_obj_t)&internal_flash_obj; -} - -STATIC mp_obj_t internal_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); - mp_uint_t ret = internal_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_readblocks_obj, internal_flash_obj_readblocks); - -STATIC mp_obj_t internal_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - mp_uint_t ret = internal_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_writeblocks_obj, internal_flash_obj_writeblocks); - -STATIC mp_obj_t internal_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { - mp_int_t cmd = mp_obj_get_int(cmd_in); - switch (cmd) { - case BP_IOCTL_INIT: internal_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_DEINIT: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly - case BP_IOCTL_SYNC: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_count()); - case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_size()); - default: return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_ioctl_obj, internal_flash_obj_ioctl); - -STATIC const mp_rom_map_elem_t internal_flash_obj_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&internal_flash_obj_readblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&internal_flash_obj_writeblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&internal_flash_obj_ioctl_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(internal_flash_obj_locals_dict, internal_flash_obj_locals_dict_table); - -const mp_obj_type_t internal_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_InternalFlash, - .make_new = internal_flash_obj_make_new, - .locals_dict = (mp_obj_t)&internal_flash_obj_locals_dict, -}; - -void flash_init_vfs(fs_user_mount_t *vfs) { - vfs->base.type = &mp_fat_vfs_type; - vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; - vfs->fatfs.drv = vfs; - vfs->fatfs.part = 1; // flash filesystem lives on first partition - vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj; - vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj; - vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version - vfs->writeblocks[0] = (mp_obj_t)&internal_flash_obj_writeblocks_obj; - vfs->writeblocks[1] = (mp_obj_t)&internal_flash_obj; - vfs->writeblocks[2] = (mp_obj_t)internal_flash_write_blocks; // native version - vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj; - vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj; -} diff --git a/ports/atmel-samd/internal_flash.h b/ports/atmel-samd/internal_flash.h deleted file mode 100644 index 88c105386..000000000 --- a/ports/atmel-samd/internal_flash.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H -#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H - -#include - -#include "mpconfigport.h" - -#include "sam.h" - -#define FLASH_ROOT_POINTERS - -#ifdef SAMD51 -#define TOTAL_INTERNAL_FLASH_SIZE (FLASH_SIZE / 2) -#endif - -#ifdef SAMD21 -#define TOTAL_INTERNAL_FLASH_SIZE 0x010000 -#endif - -#define INTERNAL_FLASH_MEM_SEG1_START_ADDR (FLASH_SIZE - TOTAL_INTERNAL_FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) -#define INTERNAL_FLASH_PART1_START_BLOCK (0x1) -#define INTERNAL_FLASH_PART1_NUM_BLOCKS (TOTAL_INTERNAL_FLASH_SIZE / FILESYSTEM_BLOCK_SIZE) - -#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms -#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) - -void internal_flash_init(void); -uint32_t internal_flash_get_block_size(void); -uint32_t internal_flash_get_block_count(void); -void internal_flash_irq_handler(void); -void internal_flash_flush(void); -bool internal_flash_read_block(uint8_t *dest, uint32_t block); -bool internal_flash_write_block(const uint8_t *src, uint32_t block); - -// these return 0 on success, non-zero on error -mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); - -extern const struct _mp_obj_type_t internal_flash_type; - -struct _fs_user_mount_t; -void flash_init_vfs(struct _fs_user_mount_t *vfs); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index a4c763d05..3b95aefa9 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -154,6 +154,7 @@ typedef long mp_off_t; #define CIRCUITPY_MCU_FAMILY samd21 #define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" #define PORT_HEAP_SIZE (16384 + 4096) +#define SPI_FLASH_MAX_BAUDRATE 8000000 #define CIRCUITPY_DEFAULT_STACK_SIZE 4096 #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_MODULE_WEAK_LINKS (0) @@ -169,6 +170,7 @@ typedef long mp_off_t; #define CIRCUITPY_MCU_FAMILY samd51 #define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" #define PORT_HEAP_SIZE (0x20000) // 128KiB +#define SPI_FLASH_MAX_BAUDRATE 24000000 #define CIRCUITPY_DEFAULT_STACK_SIZE 8192 #define MICROPY_CPYTHON_COMPAT (1) #define MICROPY_MODULE_WEAK_LINKS (1) @@ -421,8 +423,13 @@ extern const struct _mp_obj_module_t wiznet_module; #define MP_STATE_PORT MP_STATE_VM +void run_background_tasks(void); +#define MICROPY_VM_HOOK_LOOP run_background_tasks(); +#define MICROPY_VM_HOOK_RETURN run_background_tasks(); + #include "peripherals/samd/dma.h" +#include "supervisor/flash_root_pointers.h" #if MICROPY_PY_NETWORK #define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list; #else @@ -438,9 +445,6 @@ extern const struct _mp_obj_module_t wiznet_module; mp_obj_t gamepad_singleton; \ NETWORK_ROOT_POINTERS \ -void run_background_tasks(void); -#define MICROPY_VM_HOOK_LOOP run_background_tasks(); -#define MICROPY_VM_HOOK_RETURN run_background_tasks(); #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 #define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt" diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index d5c9f2ce6..7db581dd6 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -14,6 +14,6 @@ ifeq ($(LONGINT_IMPL),LONGLONG) MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong endif - INTERNAL_LIBM = 1 +USB_SERIAL_NUMBER_LENGTH = 32 diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c index a4eca1c74..ac5b0fbca 100644 --- a/ports/atmel-samd/mphalport.c +++ b/ports/atmel-samd/mphalport.c @@ -46,43 +46,9 @@ #include "mphalport.h" #include "reset.h" #include "tick.h" -#include "usb.h" -extern struct usart_module usart_instance; extern uint32_t common_hal_mcu_processor_get_frequency(void); -int mp_hal_stdin_rx_chr(void) { - for (;;) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - // if (reload_requested) { - // return CHAR_CTRL_D; - // } - if (usb_bytes_available()) { - #ifdef MICROPY_HW_LED_RX - gpio_toggle_pin_level(MICROPY_HW_LED_RX); - #endif - return usb_read(); - } - } -} - -void mp_hal_stdout_tx_strn(const char *str, size_t len) { - #ifdef MICROPY_HW_LED_TX - gpio_toggle_pin_level(MICROPY_HW_LED_TX); - #endif - - #ifdef CIRCUITPY_BOOT_OUTPUT_FILE - if (boot_output_file != NULL) { - UINT bytes_written = 0; - f_write(boot_output_file, str, len, &bytes_written); - } - #endif - - usb_write(str, len); -} - void mp_hal_delay_ms(mp_uint_t delay) { uint64_t start_tick = ticks_ms; uint64_t duration = 0; diff --git a/ports/atmel-samd/mphalport.h b/ports/atmel-samd/mphalport.h index 3bc824d4e..64269b201 100644 --- a/ports/atmel-samd/mphalport.h +++ b/ports/atmel-samd/mphalport.h @@ -41,8 +41,6 @@ static inline mp_uint_t mp_hal_ticks_ms(void) { volatile uint8_t usb_rx_count; volatile bool mp_cdc_enabled; -FIL* boot_output_file; - int receive_usb(void); void mp_hal_set_interrupt_char(int c); diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index d0dcba251..f20fcf642 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit d0dcba251c27f629c0a89b5ced4433dd0a609ca3 +Subproject commit f20fcf642b5654ee68d7d551ea7db39716ef83bf diff --git a/ports/atmel-samd/reset.c b/ports/atmel-samd/reset.c index ba5bf9ba1..735639cc4 100644 --- a/ports/atmel-samd/reset.c +++ b/ports/atmel-samd/reset.c @@ -34,10 +34,6 @@ void reset(void) { NVIC_SystemReset(); } -void reset_to_bootloader(void) { - _bootloader_dbl_tap = DBL_TAP_MAGIC; - reset(); -} extern uint32_t _srelocate; bool bootloader_available(void) { diff --git a/ports/atmel-samd/supervisor/filesystem.c b/ports/atmel-samd/supervisor/filesystem.c deleted file mode 100644 index 8a6010951..000000000 --- a/ports/atmel-samd/supervisor/filesystem.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "extmod/vfs_fat.h" -#include "lib/oofatfs/ff.h" -#include "lib/oofatfs/diskio.h" - -#include "py/mpstate.h" - -#include "flash_api.h" - -fs_user_mount_t fs_user_mount_flash; -mp_vfs_mount_t mp_vfs_mount_flash; - -static void make_empty_file(FATFS *fatfs, const char *path) { - FIL fp; - f_open(fatfs, &fp, path, FA_WRITE | FA_CREATE_ALWAYS); - f_close(&fp); -} - -// we don't make this function static because it needs a lot of stack and we -// want it to be executed without using stack within main() function -void filesystem_init(bool create_allowed, bool force_create) { - // init the vfs object - fs_user_mount_t *vfs_fat = &fs_user_mount_flash; - vfs_fat->flags = 0; - flash_init_vfs(vfs_fat); - - // try to mount the flash - FRESULT res = f_mount(&vfs_fat->fatfs); - - if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { - // No filesystem so create a fresh one, or reformat has been requested. - uint8_t working_buf[_MAX_SS]; - res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)); - // Flush the new file system to make sure it's repaired immediately. - flash_flush(); - if (res != FR_OK) { - return; - } - - // set label - f_setlabel(&vfs_fat->fatfs, "CIRCUITPY"); - - // inhibit file indexing on MacOS - f_mkdir(&vfs_fat->fatfs, "/.fseventsd"); - make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index"); - make_empty_file(&vfs_fat->fatfs, "/.Trashes"); - make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log"); - - // and ensure everything is flushed - flash_flush(); - } else if (res != FR_OK) { - return; - } - mp_vfs_mount_t *vfs = &mp_vfs_mount_flash; - vfs->str = "/"; - vfs->len = 1; - vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); - vfs->next = NULL; - MP_STATE_VM(vfs_mount_table) = vfs; - - // The current directory is used as the boot up directory. - // It is set to the internal flash filesystem by default. - MP_STATE_PORT(vfs_cur) = vfs; -} - -void filesystem_flush(void) { - flash_flush(); -} - -void filesystem_writable_by_python(bool writable) { - flash_set_usb_writable(!writable); -} - -bool filesystem_present(void) { - return true; -} diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c new file mode 100644 index 000000000..bf12ad0cd --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -0,0 +1,209 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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 +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif +#include "hal/include/hal_flash.h" + +#include "supervisor/shared/rgb_led_status.h" + +static struct flash_descriptor supervisor_flash_desc; + +void supervisor_flash_init(void) { + // Activity LED for flash writes. + #ifdef MICROPY_HW_LED_MSC + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf); + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif + + #ifdef SAMD51 + hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK); + #endif + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL); + #endif + flash_init(&supervisor_flash_desc, NVMCTRL); +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS; +} + +void supervisor_flash_flush(void) { +} + +void flash_flush(void) { + supervisor_flash_flush(); +} + +static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { + buf[0] = boot; + + if (num_blocks == 0) { + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + } else { + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + } + + buf[4] = type; + + if (num_blocks == 0) { + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + } else { + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xff; + } + + buf[8] = start_block; + buf[9] = start_block >> 8; + buf[10] = start_block >> 16; + buf[11] = start_block >> 24; + + buf[12] = num_blocks; + buf[13] = num_blocks >> 8; + buf[14] = num_blocks >> 16; + buf[15] = num_blocks >> 24; +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (INTERNAL_FLASH_PART1_START_BLOCK <= block && block < INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS) { + // a block in partition 1 + block -= INTERNAL_FLASH_PART1_START_BLOCK; + return INTERNAL_FLASH_MEM_SEG1_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +bool supervisor_flash_read_block(uint8_t *dest, uint32_t block) { + if (block == 0) { + // fake the MBR so we can decide on our own partition table + + for (int i = 0; i < 446; i++) { + dest[i] = 0; + } + + build_partition(dest + 446, 0, 0x01 /* FAT12 */, INTERNAL_FLASH_PART1_START_BLOCK, INTERNAL_FLASH_PART1_NUM_BLOCKS); + build_partition(dest + 462, 0, 0, 0, 0); + build_partition(dest + 478, 0, 0, 0, 0); + build_partition(dest + 494, 0, 0, 0, 0); + + dest[510] = 0x55; + dest[511] = 0xaa; + + return true; + + } else { + // non-MBR block, get data from flash memory + int32_t src = convert_block_to_flash_addr(block); + if (src == -1) { + // bad block number + return false; + } + int32_t error_code = flash_read(&supervisor_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE); + return error_code == ERR_NONE; + } +} + +bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { + if (block == 0) { + // can't write MBR, but pretend we did + return true; + + } else { + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + temp_status_color(ACTIVE_WRITE); + // non-MBR block, copy to cache + int32_t dest = convert_block_to_flash_addr(block); + if (dest == -1) { + // bad block number + return false; + } + int32_t error_code; + error_code = flash_erase(&supervisor_flash_desc, + dest, + FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&supervisor_flash_desc)); + if (error_code != ERR_NONE) { + return false; + } + + error_code = flash_append(&supervisor_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE); + if (error_code != ERR_NONE) { + return false; + } + clear_temp_status(); + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif + return true; + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!supervisor_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h new file mode 100644 index 000000000..88c105386 --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash.h @@ -0,0 +1,69 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H + +#include + +#include "mpconfigport.h" + +#include "sam.h" + +#define FLASH_ROOT_POINTERS + +#ifdef SAMD51 +#define TOTAL_INTERNAL_FLASH_SIZE (FLASH_SIZE / 2) +#endif + +#ifdef SAMD21 +#define TOTAL_INTERNAL_FLASH_SIZE 0x010000 +#endif + +#define INTERNAL_FLASH_MEM_SEG1_START_ADDR (FLASH_SIZE - TOTAL_INTERNAL_FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) +#define INTERNAL_FLASH_PART1_START_BLOCK (0x1) +#define INTERNAL_FLASH_PART1_NUM_BLOCKS (TOTAL_INTERNAL_FLASH_SIZE / FILESYSTEM_BLOCK_SIZE) + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +void internal_flash_init(void); +uint32_t internal_flash_get_block_size(void); +uint32_t internal_flash_get_block_count(void); +void internal_flash_irq_handler(void); +void internal_flash_flush(void); +bool internal_flash_read_block(uint8_t *dest, uint32_t block); +bool internal_flash_write_block(const uint8_t *src, uint32_t block); + +// these return 0 on success, non-zero on error +mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); +mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); + +extern const struct _mp_obj_type_t internal_flash_type; + +struct _fs_user_mount_t; +void flash_init_vfs(struct _fs_user_mount_t *vfs); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H diff --git a/ports/atmel-samd/supervisor/internal_flash_root_pointers.h b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h new file mode 100644 index 000000000..3e9148ce0 --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 45b8ed1a4..9f951b035 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -32,7 +32,6 @@ #include "hal/include/hal_delay.h" #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" -#include "hal/include/hal_usb_device.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl/pm/hpl_pm_base.h" @@ -48,13 +47,13 @@ #include "common-hal/audiobusio/PDMIn.h" #include "common-hal/audiobusio/I2SOut.h" #include "common-hal/audioio/AudioOut.h" +#include "common-hal/busio/SPI.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/pulseio/PulseIn.h" #include "common-hal/pulseio/PulseOut.h" #include "common-hal/pulseio/PWMOut.h" #include "common-hal/rtc/RTC.h" #include "common-hal/touchio/TouchIn.h" -#include "common-hal/usb_hid/Device.h" #include "samd/cache.h" #include "samd/clocks.h" #include "samd/events.h" @@ -62,8 +61,10 @@ #include "samd/dma.h" #include "shared-bindings/rtc/__init__.h" #include "board_busses.h" +#include "reset.h" #include "tick.h" -#include "usb.h" + +#include "tusb.h" #ifdef CIRCUITPY_GAMEPAD_TICKS #include "shared-module/gamepad/__init__.h" @@ -225,28 +226,7 @@ safe_mode_t port_init(void) { } void reset_port(void) { - // Reset all SERCOMs except the ones being used by on-board devices. - Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; - for (int i = 0; i < SERCOM_INST_NUM; i++) { -#ifdef SPI_FLASH_SERCOM - if (sercom_instances[i] == SPI_FLASH_SERCOM) { - continue; - } -#endif -#ifdef MICROPY_HW_APA102_SERCOM - if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) { - continue; - } -#endif -#ifdef CIRCUITPY_DISPLAYIO - // TODO(tannewt): Make this dynamic. - if (sercom_instances[i] == board_display_obj.bus.spi_desc.dev.prvt) { - continue; - } -#endif - // SWRST is same for all modes of SERCOMs. - sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1; - } + reset_sercoms(); #if defined(EXPRESS_BOARD) && !defined(__SAMR21G18A__) audio_dma_reset(); @@ -290,13 +270,16 @@ void reset_port(void) { // gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6 // #endif - usb_hid_reset(); - - if (usb_connected()) { + if (tud_cdc_connected()) { save_usb_clock_calibration(); } } +void reset_to_bootloader(void) { + _bootloader_dbl_tap = DBL_TAP_MAGIC; + reset(); +} + /** * \brief Default interrupt handler for unused IRQs. */ diff --git a/ports/atmel-samd/supervisor/qspi_flash.c b/ports/atmel-samd/supervisor/qspi_flash.c new file mode 100644 index 000000000..eca47b164 --- /dev/null +++ b/ports/atmel-samd/supervisor/qspi_flash.c @@ -0,0 +1,232 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL + +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/qspi_flash.h" +#include "samd/cache.h" +#include "samd/dma.h" + +#include "atmel_start_pins.h" +#include "hal_gpio.h" + +bool spi_flash_command(uint8_t command) { + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READ | + QSPI_INSTRFRAME_INSTREN; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + return true; +} + +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READ | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_DATAEN; + + // Dummy read of INSTRFRAME needed to synchronize. + // See Instruction Transmission Flow Diagram, figure 37.9, page 995 + // and Example 4, page 998, section 37.6.8.5. + (volatile uint32_t) QSPI->INSTRFRAME.reg; + + memcpy(response, (uint8_t *) QSPI_AHB, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITE | + QSPI_INSTRFRAME_INSTREN | + (data != NULL ? QSPI_INSTRFRAME_DATAEN : 0); + + // Dummy read of INSTRFRAME needed to synchronize. + // See Instruction Transmission Flow Diagram, figure 37.9, page 995 + // and Example 4, page 998, section 37.6.8.5. + (volatile uint32_t) QSPI->INSTRFRAME.reg; + + if (data != NULL) { + memcpy((uint8_t *) QSPI_AHB, data, length); + } + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + QSPI->INSTRCTRL.bit.INSTR = command; + QSPI->INSTRADDR.bit.ADDR = address; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITE | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + return true; +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = CMD_PAGE_PROGRAM; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI; + + QSPI->INSTRFRAME.reg = mode | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITEMEMORY | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN | + QSPI_INSTRFRAME_DATAEN; + + memcpy(((uint8_t *) QSPI_AHB) + address, data, length); + // TODO(tannewt): Fix DMA and enable it. + // qspi_dma_write(address, data, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + #ifdef EXTERNAL_FLASH_QSPI_DUAL + QSPI->INSTRCTRL.bit.INSTR = CMD_DUAL_READ; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_DUAL_OUTPUT; + #else + QSPI->INSTRCTRL.bit.INSTR = CMD_QUAD_READ; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_QUAD_OUTPUT; + #endif + + QSPI->INSTRFRAME.reg = mode | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READMEMORY | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN | + QSPI_INSTRFRAME_DATAEN | + QSPI_INSTRFRAME_DUMMYLEN(8); + + memcpy(data, ((uint8_t *) QSPI_AHB) + address, length); + // TODO(tannewt): Fix DMA and enable it. + // qspi_dma_read(address, data, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + + +void spi_flash_init(void) { + MCLK->APBCMASK.bit.QSPI_ = true; + MCLK->AHBMASK.bit.QSPI_ = true; + MCLK->AHBMASK.bit.QSPI_2X_ = false; // Only true if we are doing DDR. + + QSPI->CTRLA.reg = QSPI_CTRLA_SWRST; + // We don't need to wait because we're running as fast as the CPU. + + // Slow, good for debugging with Saleae + // QSPI->BAUD.bit.BAUD = 32; + // Super fast, may be unreliable when Saleae is connected to high speed lines. + QSPI->BAUD.bit.BAUD = 2; + QSPI->CTRLB.reg = QSPI_CTRLB_MODE_MEMORY | // Serial memory mode (map to QSPI_AHB) + QSPI_CTRLB_DATALEN_8BITS | + QSPI_CTRLB_CSMODE_LASTXFER; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE; + + // The QSPI is only connected to one set of pins in the SAMD51 so we can hard code it. + uint32_t pins[6] = {PIN_PA08, PIN_PA09, PIN_PA10, PIN_PA11, PIN_PB10, PIN_PB11}; + for (uint8_t i = 0; i < 6; i++) { + gpio_set_pin_direction(pins[i], GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(pins[i], GPIO_PULL_OFF); + gpio_set_pin_function(pins[i], GPIO_PIN_FUNCTION_H); + } +} + +void spi_flash_init_device(const external_flash_device* device) { + check_quad_enable(device); + + // TODO(tannewt): Adjust the speed for the found device. +} diff --git a/ports/atmel-samd/supervisor/serial.c b/ports/atmel-samd/supervisor/serial.c deleted file mode 100644 index 4917dfb5b..000000000 --- a/ports/atmel-samd/supervisor/serial.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 - -#include "supervisor/serial.h" - -#include "common-hal/usb_hid/Device.h" - -#include "usb.h" -#include "genhdr/autogen_usb_descriptor.h" - -// Serial number as hex characters. This writes directly to the USB -// descriptor. -void load_serial_number(void) { - char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; - #ifdef SAMD21 - uint32_t* addresses[4] = {(uint32_t *) 0x0080A00C, (uint32_t *) 0x0080A040, - (uint32_t *) 0x0080A044, (uint32_t *) 0x0080A048}; - #endif - #ifdef SAMD51 - uint32_t* addresses[4] = {(uint32_t *) 0x008061FC, (uint32_t *) 0x00806010, - (uint32_t *) 0x00806014, (uint32_t *) 0x00806018}; - #endif - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 8; j++) { - uint8_t nibble = (*(addresses[i]) >> j * 4) & 0xf; - // Strings are UTF-16-LE encoded. - serial_number[i * 16 + j * 2] = nibble_to_hex[nibble]; - serial_number[i * 16 + j * 2 + 1] = 0; - } - } -} - -void serial_init(void) { - load_serial_number(); - init_usb(); - usb_hid_init(); -} - -bool serial_connected(void) { - return usb_connected(); -} - -char serial_read(void) { - return usb_read(); -} - -bool serial_bytes_available(void) { - return usb_bytes_available(); -} - -void serial_write(const char* text) { - usb_write(text, strlen(text)); -} diff --git a/ports/atmel-samd/supervisor/usb.c b/ports/atmel-samd/supervisor/usb.c new file mode 100644 index 000000000..d13ca0ef1 --- /dev/null +++ b/ports/atmel-samd/supervisor/usb.c @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "atmel_start_pins.h" +#include "hpl/pm/hpl_pm_base.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hal_gpio.h" + +void init_usb_hardware(void) { + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBB, USB); + _pm_enable_bus_clock(PM_BUS_AHB, USB); + _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + #endif + + #ifdef SAMD51 + hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); + hri_mclk_set_AHBMASK_USB_bit(MCLK); + hri_mclk_set_APBBMASK_USB_bit(MCLK); + #endif + + gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA24, false); + gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); + gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA25, false); + gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); + #ifdef SAMD21 + gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP); + #endif + #ifdef SAMD51 + gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); + #endif +} diff --git a/ports/atmel-samd/tick.h b/ports/atmel-samd/tick.h index 80e7bc9af..c8c8d739a 100644 --- a/ports/atmel-samd/tick.h +++ b/ports/atmel-samd/tick.h @@ -26,7 +26,7 @@ #ifndef MICROPY_INCLUDED_ATMEL_SAMD_TICK_H #define MICROPY_INCLUDED_ATMEL_SAMD_TICK_H -#include "mpconfigport.h" +#include "py/mpconfig.h" extern volatile uint64_t ticks_ms; diff --git a/ports/atmel-samd/tools/gen_usb_descriptor.py b/ports/atmel-samd/tools/gen_usb_descriptor.py deleted file mode 100644 index efa8124bf..000000000 --- a/ports/atmel-samd/tools/gen_usb_descriptor.py +++ /dev/null @@ -1,353 +0,0 @@ -import argparse - -import os -import sys - -# path hacking -sys.path.append("../../tools/usb_descriptor") - -from adafruit_usb_descriptor import cdc, hid, msc, standard, util -import hid_report_descriptors - -parser = argparse.ArgumentParser(description='Generate USB descriptors.') -parser.add_argument('--manufacturer', type=str, - help='manufacturer of the device') -parser.add_argument('--product', type=str, - help='product name of the device') -parser.add_argument('--vid', type=lambda x: int(x, 16), - help='vendor id') -parser.add_argument('--pid', type=lambda x: int(x, 16), - help='product id') -parser.add_argument('--serial_number_length', type=int, default=32, - help='length needed for the serial number in digits') -parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) -parser.add_argument('--output_h_file', type=argparse.FileType('w'), required=True) - -args = parser.parse_args() - -class StringIndex: - """Assign a monotonically increasing index to each unique string. Start with 0.""" - string_to_index = {} - strings = [] - - @classmethod - def index(cls, string): - if string in cls.string_to_index: - return cls.string_to_index[string] - else: - idx = len(cls.strings) - cls.string_to_index[string] = idx - cls.strings.append(string) - return idx - - @classmethod - def strings_in_order(cls): - return cls.strings - - - -# langid must be the 0th string descriptor -LANGID_INDEX = StringIndex.index("\u0409") -assert LANGID_INDEX == 0 -SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length) - -device = standard.DeviceDescriptor( - description="top", - idVendor=args.vid, - idProduct=args.pid, - iManufacturer=StringIndex.index(args.manufacturer), - iProduct=StringIndex.index(args.product), - iSerialNumber=SERIAL_NUMBER_INDEX) - -# Interface numbers are interface-set local and endpoints are interface local -# until util.join_interfaces renumbers them. - -cdc_union = cdc.Union( - description="CDC comm", - bMasterInterface=0x00, # Adjust this after interfaces are renumbered. - bSlaveInterface_list=[0x01]) # Adjust this after interfaces are renumbered. - -cdc_call_management = cdc.CallManagement( - description="CDC comm", - bmCapabilities=0x01, - bDataInterface=0x01) # Adjust this after interfaces are renumbered. - -cdc_comm_interface = standard.InterfaceDescriptor( - description="CDC comm", - bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class - bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, - iInterface=StringIndex.index("CircuitPython CDC control"), - subdescriptors=[ - cdc.Header( - description="CDC comm", - bcdCDC=0x0110), - cdc_call_management, - cdc.AbstractControlManagement( - description="CDC comm", - bmCapabilities=0x02), - cdc_union, - standard.EndpointDescriptor( - description="CDC comm in", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - wMaxPacketSize=0x0040, - bInterval=0x10) - ]) - -cdc_data_interface = standard.InterfaceDescriptor( - description="CDC data", - bInterfaceClass=cdc.CDC_CLASS_DATA, - iInterface=StringIndex.index("CircuitPython CDC data"), - subdescriptors=[ - standard.EndpointDescriptor( - description="CDC data out", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - standard.EndpointDescriptor( - description="CDC data in", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK), - ]) - -cdc_interfaces = [cdc_comm_interface, cdc_data_interface] - -msc_interfaces = [ - standard.InterfaceDescriptor( - description="MSC", - bInterfaceClass=msc.MSC_CLASS, - bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, - bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, - iInterface=StringIndex.index("CircuitPython Mass Storage"), - subdescriptors=[ - standard.EndpointDescriptor( - description="MSC in", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0), - standard.EndpointDescriptor( - description="MSC out", - bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0) - ] - ) -] - -# Include only these HID devices. -# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now. -hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD") - -combined_hid_report_descriptor = hid.ReportDescriptor( - description="MULTIDEVICE", - report_descriptor=b''.join( - hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices )) - -hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices } -hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices } -hid_max_report_length = max(hid_report_lengths_dict.values()) - -# ASF4 expects keyboard and generic devices to have both in and out endpoints, -# and will fail (possibly silently) if both are not supplied. -hid_endpoint_in_descriptor = standard.EndpointDescriptor( - description="HID in", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - bInterval=10) - -hid_endpoint_out_descriptor = standard.EndpointDescriptor( - description="HID out", - bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - bInterval=10) - -hid_interfaces = [ - standard.InterfaceDescriptor( - description="HID Multiple Devices", - bInterfaceClass=hid.HID_CLASS, - bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT, - bInterfaceProtocol=hid.HID_PROTOCOL_NONE, - iInterface=StringIndex.index("CircuitPython HID"), - subdescriptors=[ - hid.HIDDescriptor( - description="HID", - wDescriptorLength=len(bytes(combined_hid_report_descriptor))), - hid_endpoint_in_descriptor, - hid_endpoint_out_descriptor, - ] - ), - ] - -# This will renumber the endpoints to make them unique across descriptors, -# and renumber the interfaces in order. But we still need to fix up certain -# interface cross-references. -interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces) - -# Now adjust the CDC interface cross-references. - -cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber -cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber] - -cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber - -cdc_iad = standard.InterfaceAssociationDescriptor( - description="CDC IAD", - bFirstInterface=cdc_comm_interface.bInterfaceNumber, - bInterfaceCount=len(cdc_interfaces), - bFunctionClass=0x2, # Communications Device Class - bFunctionSubClass=0x2, # Abstract control model - bFunctionProtocol=0x1) - -configuration = standard.ConfigurationDescriptor( - description="Composite configuration", - wTotalLength=(standard.ConfigurationDescriptor.bLength + - cdc_iad.bLength + - sum([len(bytes(x)) for x in interfaces])), - bNumInterfaces=len(interfaces)) - -descriptor_list = [] -descriptor_list.append(device) -descriptor_list.append(configuration) -descriptor_list.append(cdc_iad) -descriptor_list.extend(cdc_interfaces) -descriptor_list.extend(msc_interfaces) -# Put the CDC IAD just before the CDC interfaces. -# There appears to be a bug in the Windows composite USB driver that requests the -# HID report descriptor with the wrong interface number if the HID interface is not given -# first. However, it still fetches the descriptor anyway. We could reorder the interfaces but -# the Windows 7 Adafruit_usbser.inf file thinks CDC is at Interface 0, so we'll leave it -# there for backwards compatibility. -descriptor_list.extend(hid_interfaces) - -string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()] -serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX] -descriptor_list.extend(string_descriptors) - -c_file = args.output_c_file -h_file = args.output_h_file - - -c_file.write("""\ -#include - -#include "{H_FILE_NAME}" - -#include "usb/device/usbdc.h" - -""".format(H_FILE_NAME=h_file.name)) - -c_file.write("""\ -uint8_t usb_descriptors[] = { -""") - -# Write out all the regular descriptors as one long array (that's how ASF4 does it). -descriptor_length = 0 -serial_number_offset = None -for descriptor in descriptor_list: - c_file.write("""\ -// {DESCRIPTION} : {CLASS} -""".format(DESCRIPTION=descriptor.description, - CLASS=descriptor.__class__)) - - b = bytes(descriptor) - i = 0 - - if descriptor == serial_number_descriptor: - # Add two for bLength and bDescriptorType. - serial_number_offset = descriptor_length + 2 - - # This prints each subdescriptor on a separate line. - while i < len(b): - length = b[i] - for j in range(length): - c_file.write("0x{:02x}, ".format(b[i + j])) - c_file.write("\n") - i += length - descriptor_length += length - - -c_file.write("""\ -}; -""") - -# Now we values we need for the .h file. -h_file.write("""\ -#ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H -#define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H - -#define SERIAL_NUMBER_OFFSET {SERIAL_NUMBER_OFFSET} -#define SERIAL_NUMBER_LENGTH {SERIAL_NUMBER_LENGTH} -uint8_t* serial_number; - -uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}]; -#define USB_HID_ENDPOINT_IN {HID_ENDPOINT_IN_ADDRESS} -#define USB_HID_ENDPOINT_OUT {HID_ENDPOINT_OUT_ADDRESS} - -""" -.format(SERIAL_NUMBER_OFFSET=serial_number_offset, - SERIAL_NUMBER_LENGTH=args.serial_number_length, - HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)), - HID_ENDPOINT_IN_ADDRESS=hex(hid_endpoint_in_descriptor.bEndpointAddress), - HID_ENDPOINT_OUT_ADDRESS=hex(hid_endpoint_out_descriptor.bEndpointAddress))) - -# Write out #define's that declare which endpoints are in use. -# These provide information for declaring cache sizes and perhaps other things at compile time -for interface in interfaces: - for subdescriptor in interface.subdescriptors: - if isinstance(subdescriptor, standard.EndpointDescriptor): - endpoint_num = subdescriptor.bEndpointAddress & standard.EndpointDescriptor.NUMBER_MASK - endpoint_in = ((subdescriptor.bEndpointAddress & standard.EndpointDescriptor.DIRECTION_MASK) == - standard.EndpointDescriptor.DIRECTION_IN) - h_file.write("""\ -#define USB_ENDPOINT_{NUMBER}_{DIRECTION}_USED 1 -""".format(NUMBER=endpoint_num, - DIRECTION="IN" if endpoint_in else "OUT")) - -h_file.write("\n") - -# #define the report ID's used in the combined HID descriptor -for name, id in hid_report_ids_dict.items(): - h_file.write("""\ -#define USB_HID_REPORT_ID_{NAME} {ID} -""".format(NAME=name, - ID = id)) - -h_file.write("\n") - -# #define the report sizes used in the combined HID descriptor -for name, length in hid_report_lengths_dict.items(): - h_file.write("""\ -#define USB_HID_REPORT_LENGTH_{NAME} {LENGTH} -""".format(NAME=name, - LENGTH=length)) - -h_file.write("\n") - -h_file.write("""\ -#define USB_HID_NUM_DEVICES {NUM_DEVICES} -#define USB_HID_MAX_REPORT_LENGTH {MAX_LENGTH} -""".format(NUM_DEVICES=len(hid_report_lengths_dict), - MAX_LENGTH=hid_max_report_length)) - - - -# Write out the report descriptor and info -c_file.write("""\ -uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{ -""".format(HID_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)))) - -for b in bytes(combined_hid_report_descriptor): - c_file.write("0x{:02x}, ".format(b)) -c_file.write(""" -}; -""") - -c_file.write("""\ - -struct usbd_descriptors descriptor_bounds = {{usb_descriptors, usb_descriptors + sizeof(usb_descriptors)}}; -uint8_t* serial_number = usb_descriptors + {SERIAL_NUMBER_OFFSET}; -""".format(SERIAL_NUMBER_OFFSET=serial_number_offset)) - -h_file.write("""\ -#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H -""") diff --git a/ports/atmel-samd/tools/hid_report_descriptors.py b/ports/atmel-samd/tools/hid_report_descriptors.py deleted file mode 100644 index f3b28ebcf..000000000 --- a/ports/atmel-samd/tools/hid_report_descriptors.py +++ /dev/null @@ -1,239 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Dan Halbert for Adafruit Industries -# -# 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. - -import struct - -""" -HID specific descriptors -======================== - -* Author(s): Dan Halbert -""" - -from adafruit_usb_descriptor import hid - -REPORT_IDS = { - "KEYBOARD" : 1, - "MOUSE" : 2, - "CONSUMER" : 3, - "SYS_CONTROL" : 4, - "GAMEPAD" : 5, - "DIGITIZER" : 6, - } - -# Byte count for each kind of report. Length does not include report ID in first byte. -REPORT_LENGTHS = { - "KEYBOARD" : 8, - "MOUSE" : 4, - "CONSUMER" : 2, - "SYS_CONTROL" : 1, - "GAMEPAD" : 6, - "DIGITIZER" : 5, - } - -KEYBOARD_WITH_ID = hid.ReportDescriptor( - description="KEYBOARD", - report_descriptor=bytes([ - # Regular keyboard - 0x05, 0x01, # Usage Page (Generic Desktop) - 0x09, 0x06, # Usage (Keyboard) - 0xA1, 0x01, # Collection (Application) - 0x85, REPORT_IDS["KEYBOARD"], # Report ID (1) - 0x05, 0x07, # Usage Page (Keyboard) - 0x19, 224, # Usage Minimum (224) - 0x29, 231, # Usage Maximum (231) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 0x01, # Logical Maximum (1) - 0x75, 0x01, # Report Size (1) - 0x95, 0x08, # Report Count (8) - 0x81, 0x02, # Input (Data, Variable, Absolute) - 0x81, 0x01, # Input (Constant) - 0x19, 0x00, # Usage Minimum (0) - 0x29, 101, # Usage Maximum (101) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 101, # Logical Maximum (101) - 0x75, 0x08, # Report Size (8) - 0x95, 0x06, # Report Count (6) - 0x81, 0x00, # Input (Data, Array) - 0x05, 0x08, # Usage Page (LED) - 0x19, 0x01, # Usage Minimum (1) - 0x29, 0x05, # Usage Maximum (5) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 0x01, # Logical Maximum (1) - 0x75, 0x01, # Report Size (1) - 0x95, 0x05, # Report Count (5) - 0x91, 0x02, # Output (Data, Variable, Absolute) - 0x95, 0x03, # Report Count (3) - 0x91, 0x01, # Output (Constant) - 0xC0, # End Collection - ])) - -MOUSE_WITH_ID = hid.ReportDescriptor( - description="MOUSE", - report_descriptor=bytes([ - # Regular mouse - 0x05, 0x01, # Usage Page (Generic Desktop) - 0x09, 0x02, # Usage (Mouse) - 0xA1, 0x01, # Collection (Application) - 0x09, 0x01, # Usage (Pointer) - 0xA1, 0x00, # Collection (Physical) - 0x85, REPORT_IDS["MOUSE"], # Report ID (n) - 0x05, 0x09, # Usage Page (Button) - 0x19, 0x01, # Usage Minimum (0x01) - 0x29, 0x05, # Usage Maximum (0x05) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 0x01, # Logical Maximum (1) - 0x95, 0x05, # Report Count (5) - 0x75, 0x01, # Report Size (1) - 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x95, 0x01, # Report Count (1) - 0x75, 0x03, # Report Size (3) - 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) - 0x09, 0x30, # Usage (X) - 0x09, 0x31, # Usage (Y) - 0x15, 0x81, # Logical Minimum (-127) - 0x25, 0x7F, # Logical Maximum (127) - 0x75, 0x08, # Report Size (8) - 0x95, 0x02, # Report Count (2) - 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) - 0x09, 0x38, # Usage (Wheel) - 0x15, 0x81, # Logical Minimum (-127) - 0x25, 0x7F, # Logical Maximum (127) - 0x75, 0x08, # Report Size (8) - 0x95, 0x01, # Report Count (1) - 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, # End Collection - 0xC0, # End Collection - ])) - -CONSUMER_WITH_ID = hid.ReportDescriptor( - description="CONSUMER", - report_descriptor=bytes([ - # Consumer ("multimedia") keys - 0x05, 0x0C, # Usage Page (Consumer) - 0x09, 0x01, # Usage (Consumer Control) - 0xA1, 0x01, # Collection (Application) - 0x85, REPORT_IDS["CONSUMER"], # Report ID (n) - 0x75, 0x10, # Report Size (16) - 0x95, 0x01, # Report Count (1) - 0x15, 0x01, # Logical Minimum (1) - 0x26, 0x8C, 0x02, # Logical Maximum (652) - 0x19, 0x01, # Usage Minimum (Consumer Control) - 0x2A, 0x8C, 0x02, # Usage Maximum (AC Send) - 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, # End Collection - ])) - -SYS_CONTROL_WITH_ID = hid.ReportDescriptor( - description="SYS_CONTROL", - report_descriptor=bytes([ - # Power controls - 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) - 0x09, 0x80, # Usage (Sys Control) - 0xA1, 0x01, # Collection (Application) - 0x85, REPORT_IDS["SYS_CONTROL"], # Report ID (n) - 0x75, 0x02, # Report Size (2) - 0x95, 0x01, # Report Count (1) - 0x15, 0x01, # Logical Minimum (1) - 0x25, 0x03, # Logical Maximum (3) - 0x09, 0x82, # Usage (Sys Sleep) - 0x09, 0x81, # Usage (Sys Power Down) - 0x09, 0x83, # Usage (Sys Wake Up) - 0x81, 0x60, # Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) - 0x75, 0x06, # Report Size (6) - 0x81, 0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, # End Collection - ])) - -GAMEPAD_WITH_ID = hid.ReportDescriptor( - description="GAMEPAD", - report_descriptor=bytes([ - # Gamepad with 16 buttons and two joysticks - 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) - 0x09, 0x05, # Usage (Game Pad) - 0xA1, 0x01, # Collection (Application) - 0x85, REPORT_IDS["GAMEPAD"], # Report ID (n) - 0x05, 0x09, # Usage Page (Button) - 0x19, 0x01, # Usage Minimum (Button 1) - 0x29, 0x10, # Usage Maximum (Button 16) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 0x01, # Logical Maximum (1) - 0x75, 0x01, # Report Size (1) - 0x95, 0x10, # Report Count (16) - 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) - 0x15, 0x81, # Logical Minimum (-127) - 0x25, 0x7F, # Logical Maximum (127) - 0x09, 0x30, # Usage (X) - 0x09, 0x31, # Usage (Y) - 0x09, 0x32, # Usage (Z) - 0x09, 0x35, # Usage (Rz) - 0x75, 0x08, # Report Size (8) - 0x95, 0x04, # Report Count (4) - 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, # End Collection - ])) - -DIGITIZER_WITH_ID = hid.ReportDescriptor( - description="DIGITIZER", - report_descriptor=bytes([ - # Digitizer (used as an absolute pointer) - 0x05, 0x0D, # Usage Page (Digitizers) - 0x09, 0x02, # Usage (Pen) - 0xA1, 0x01, # Collection (Application) - 0x85, REPORT_IDS["DIGITIZER"], # Report ID (n) - 0x09, 0x01, # Usage (Stylus) - 0xA1, 0x00, # Collection (Physical) - 0x09, 0x32, # Usage (In-Range) - 0x09, 0x42, # Usage (Tip Switch) - 0x09, 0x44, # Usage (Barrel Switch) - 0x09, 0x45, # Usage (Eraser Switch) - 0x15, 0x00, # Logical Minimum (0) - 0x25, 0x01, # Logical Maximum (1) - 0x75, 0x01, # Report Size (1) - 0x95, 0x04, # Report Count (4) - 0x81, 0x02, # Input (Data,Var,Abs) - 0x75, 0x04, # Report Size (4) -- Filler - 0x95, 0x01, # Report Count (1) -- Filler - 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) - 0x15, 0x00, # Logical Minimum (0) - 0x26, 0xff, 0x7f, # Logical Maximum (32767) - 0x09, 0x30, # Usage (X) - 0x09, 0x31, # Usage (Y) - 0x75, 0x10, # Report Size (16) - 0x95, 0x02, # Report Count (2) - 0x81, 0x02, # Input (Data,Var,Abs) - 0xC0, # End Collection - 0xC0, # End Collection - ])) - -# Byte count for each kind of report. Length does not include report ID in first byte. -REPORT_DESCRIPTORS = { - "KEYBOARD" : KEYBOARD_WITH_ID, - "MOUSE" : MOUSE_WITH_ID, - "CONSUMER" : CONSUMER_WITH_ID, - "SYS_CONTROL" : SYS_CONTROL_WITH_ID, - "GAMEPAD" : GAMEPAD_WITH_ID, - "DIGITIZER" : DIGITIZER_WITH_ID, - } diff --git a/ports/atmel-samd/usb.c b/ports/atmel-samd/usb.c deleted file mode 100644 index 1f1ba550f..000000000 --- a/ports/atmel-samd/usb.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "usb.h" - -#include - -// We must include this early because it sets values used in the ASF4 includes -// below. -#include "py/mpconfig.h" - -#include "hal/include/hal_gpio.h" -#include "usb/class/cdc/device/cdcdf_acm.h" -#include "usb/class/hid/device/hiddf_generic.h" -#include "usb/class/composite/device/composite_desc.h" -#include "usb/class/msc/device/mscdf.h" -#include "peripheral_clk_config.h" -#include "hpl/pm/hpl_pm_base.h" -#include "hpl/gclk/hpl_gclk_base.h" - -#include "lib/utils/interrupt_char.h" -#include "genhdr/autogen_usb_descriptor.h" -#include "reset.h" -#include "usb_mass_storage.h" - -#include "supervisor/shared/autoreload.h" - -extern struct usbd_descriptors descriptor_bounds; - -// Store received characters on our own so that we can filter control characters -// and act immediately on CTRL-C for example. - -// Receive buffer -static uint8_t usb_rx_buf[USB_RX_BUF_SIZE]; - -// Receive buffer head -static volatile uint8_t usb_rx_buf_head = 0; - -// Receive buffer tail -static volatile uint8_t usb_rx_buf_tail = 0; - -// Number of bytes in receive buffer -volatile uint8_t usb_rx_count = 0; - -volatile bool mp_cdc_enabled = false; -volatile bool usb_transmitting = false; - -/** Ctrl endpoint buffer */ -COMPILER_ALIGNED(4) static uint8_t ctrl_buffer[64]; - -static void init_hardware(void) { - #ifdef SAMD21 - _pm_enable_bus_clock(PM_BUS_APBB, USB); - _pm_enable_bus_clock(PM_BUS_AHB, USB); - _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); - #endif - - #ifdef SAMD51 - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, CONF_GCLK_USB_SRC | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - #endif - - usb_d_init(); - - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - #ifdef SAMD21 - gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP); - #endif - #ifdef SAMD51 - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - #endif -} - -#define CDC_BULKOUT_SIZE CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ -COMPILER_ALIGNED(4) uint8_t cdc_packet_buffer[CDC_BULKOUT_SIZE]; -static volatile bool pending_read; - -static int32_t start_read(void) { - pending_read = true; - int32_t result = cdcdf_acm_read(cdc_packet_buffer, CDC_BULKOUT_SIZE); - if (result != ERR_NONE) { - pending_read = false; - } - return result; -} - -static bool read_complete(const uint8_t ep, const enum usb_xfer_code rc, const uint32_t count) { - if (rc != USB_XFER_DONE) { - return false; // No errors. - } - pending_read = false; - volatile hal_atomic_t flags; - atomic_enter_critical(&flags); - // If our buffer can't fit the data received, then error out. - if (count > (uint8_t) (USB_RX_BUF_SIZE - usb_rx_count)) { - atomic_leave_critical(&flags); - return true; - } - - for (uint16_t i = 0; i < count; i++) { - uint8_t c = cdc_packet_buffer[i]; - if (c == mp_interrupt_char) { - mp_keyboard_interrupt(); - // If interrupted, flush all the input. - usb_rx_count = 0; - usb_rx_buf_head = 0; - usb_rx_buf_tail = 0; - break; - } else { - // The count of characters present in receive buffer is - // incremented. - usb_rx_count++; - usb_rx_buf[usb_rx_buf_tail] = c; - usb_rx_buf_tail++; - if (usb_rx_buf_tail == USB_RX_BUF_SIZE) { - // Reached the end of buffer, revert back to beginning of - // buffer. - usb_rx_buf_tail = 0; - } - } - } - atomic_leave_critical(&flags); - - /* No error. */ - return false; -} - -static bool write_complete(const uint8_t ep, - const enum usb_xfer_code rc, - const uint32_t count) { - if (rc != USB_XFER_DONE) { - return false; // No errors. - } - // This is called after writes are finished. - - usb_transmitting = false; - - /* No error. */ - return false; -} - -volatile bool reset_on_disconnect = false; -volatile bool cdc_connected = false; - -static bool usb_device_cb_state_c(usb_cdc_control_signal_t state) -{ - cdc_connected = state.rs232.DTR; - if (state.rs232.DTR) { - } else if (!state.rs232.DTR && reset_on_disconnect) { - reset_to_bootloader(); - } - - /* No error. */ - return false; -} - -static bool usb_device_cb_line_coding_c(const usb_cdc_line_coding_t* coding) -{ - reset_on_disconnect = coding->dwDTERate == 1200; - /* Ok to change. */ - return true; -} - -void init_usb(void) { - init_hardware(); - - mp_cdc_enabled = false; - - usbdc_init(ctrl_buffer); - - /* usbdc_register_function inside */ - cdcdf_acm_init(); - pending_read = false; - - mscdf_init(1); - mscdf_register_callback(MSCDF_CB_INQUIRY_DISK, (FUNC_PTR)usb_msc_inquiry_info); - mscdf_register_callback(MSCDF_CB_GET_DISK_CAPACITY, (FUNC_PTR)usb_msc_get_capacity); - mscdf_register_callback(MSCDF_CB_START_READ_DISK, (FUNC_PTR)usb_msc_new_read); - mscdf_register_callback(MSCDF_CB_START_WRITE_DISK, (FUNC_PTR)usb_msc_new_write); - mscdf_register_callback(MSCDF_CB_EJECT_DISK, (FUNC_PTR)usb_msc_disk_eject); - mscdf_register_callback(MSCDF_CB_TEST_DISK_READY, (FUNC_PTR)usb_msc_disk_is_ready); - mscdf_register_callback(MSCDF_CB_XFER_BLOCKS_DONE, (FUNC_PTR)usb_msc_xfer_done); - mscdf_register_callback(MSCDF_CB_IS_WRITABLE, (FUNC_PTR)usb_msc_disk_is_writable); - - hiddf_generic_init(hid_report_descriptor, sizeof(hid_report_descriptor)); - - usbdc_start(&descriptor_bounds); - - usbdc_attach(); - - -} - -static bool cdc_enabled(void) { - if (!cdcdf_acm_is_enabled()) { - mp_cdc_enabled = false; - return false; - } - if (!mp_cdc_enabled) { - cdcdf_acm_register_callback(CDCDF_ACM_CB_READ, (FUNC_PTR)read_complete); - cdcdf_acm_register_callback(CDCDF_ACM_CB_WRITE, (FUNC_PTR)write_complete); - cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c); - cdcdf_acm_register_callback(CDCDF_ACM_CB_LINE_CODING_C, (FUNC_PTR)usb_device_cb_line_coding_c); - mp_cdc_enabled = true; - } - - return true; -} - -bool usb_bytes_available(void) { - // Check if the buffer has data, but not enough - // space to hold another read. - if (usb_rx_count > USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE) { - return true; - } - // Buffer has enough room - if (cdc_enabled() && !pending_read) { - start_read(); - } - // Buffer is empty and/or no new data is available - if (usb_rx_count == 0) { - return false; - } - return usb_rx_count > 0; -} - -int usb_read(void) { - if (!cdc_enabled() || usb_rx_count == 0) { - return 0; - } - - // Copy from head. - int data; - CRITICAL_SECTION_ENTER(); - data = usb_rx_buf[usb_rx_buf_head]; - usb_rx_buf_head++; - usb_rx_count--; - if (usb_rx_buf_head == USB_RX_BUF_SIZE) { - usb_rx_buf_head = 0; - } - CRITICAL_SECTION_LEAVE(); - - return data; -} - -// TODO(tannewt): See if we can disable the internal CDC IN cache since we -// we manage this one ourselves. -#define CDC_BULKIN_SIZE CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ -COMPILER_ALIGNED(4) uint8_t cdc_output_buffer[CDC_BULKIN_SIZE]; - -void usb_write(const char* buffer, uint32_t len) { - if (!cdc_enabled()) { - return; - } - if (!cdc_connected) { - // TODO(tannewt): Should we write to a file instead? - return; - } - uint8_t * output_buffer; - uint32_t output_len; - while (len > 0) { - while (usb_transmitting) {} - output_buffer = (uint8_t *) buffer; - output_len = len; - // Use our own cache in two different cases: - // * When we're at the end of a transmission and we'll return before - // the given buffer is actually transferred to the USB device. - // * When our given buffer isn't aligned on word boundaries. - if (output_len <= CDC_BULKIN_SIZE || ((uint32_t) buffer) % 4 != 0) { - output_buffer = cdc_output_buffer; - output_len = output_len > CDC_BULKIN_SIZE ? CDC_BULKIN_SIZE : output_len; - memcpy(cdc_output_buffer, buffer, output_len); - } else { - output_len = CDC_BULKIN_SIZE; - } - usb_transmitting = true; - cdcdf_acm_write(output_buffer, output_len); - buffer += output_len * sizeof(char); - len -= output_len; - } -} - -bool usb_connected(void) { - return cdc_enabled(); -} - -// Poll for input if keyboard interrupts are enabled, -// so that we can check for the interrupt char. read_complete() does the checking. -// also make sure we have enough room in the local buffer -void usb_cdc_background() { - // - if (mp_interrupt_char != -1 && cdc_enabled() && !pending_read && (usb_rx_count < USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE)) { - start_read(); - } -} diff --git a/ports/atmel-samd/usb.h b/ports/atmel-samd/usb.h deleted file mode 100644 index f01c5ebfb..000000000 --- a/ports/atmel-samd/usb.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_USB_H -#define MICROPY_INCLUDED_ATMEL_SAMD_USB_H - -#include -#include - -#define USB_RX_BUF_SIZE 128 - -void init_usb(void); -int usb_read(void); -void usb_write(const char* buffer, uint32_t len); -bool usb_bytes_available(void); -bool usb_connected(void); -void usb_cdc_background(void); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_USB_H diff --git a/ports/atmel-samd/usb_mass_storage.c b/ports/atmel-samd/usb_mass_storage.c deleted file mode 100644 index 9b6715158..000000000 --- a/ports/atmel-samd/usb_mass_storage.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * 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 - -#include "usb_mass_storage.h" -#include "supervisor/shared/autoreload.h" - -#include "hal/utils/include/err_codes.h" -#include "hal/utils/include/utils.h" -#include "usb/class/msc/device/mscdf.h" - -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "lib/oofatfs/ff.h" -#include "lib/oofatfs/diskio.h" -#include "lib/oofatfs/ffconf.h" -#include "py/mpconfig.h" -#include "py/mphal.h" -#include "py/mpstate.h" -#include "py/misc.h" - -// The root FS is always at the end of the list. -static fs_user_mount_t* get_vfs(int lun) { - // TODO(tannewt): Return the mount which matches the lun where 0 is the end - // and is counted in reverse. - if (lun > 0) { - return NULL; - } - mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); - if (current_mount == NULL) { - return NULL; - } - while (current_mount->next != NULL) { - current_mount = current_mount->next; - } - return current_mount->obj; -} - -/* Inquiry Information */ -// This is designed to handle the common case where we have an internal file -// system and an optional SD card. -COMPILER_ALIGNED(4) static uint8_t inquiry_info[2][36]; - -/* Capacities of Disk */ -COMPILER_ALIGNED(4) static uint8_t format_capa[2][8]; - -/** - * \brief Eject Disk - * \param[in] lun logic unit number - * \return Operation status. - */ -int32_t usb_msc_disk_eject(uint8_t lun) { - if (lun > 1) { - return ERR_NOT_FOUND; - } - fs_user_mount_t* current_mount = get_vfs(lun); - // Return ERR_NOT_READY if not ready, otherwise ERR_NONE. - if (current_mount == NULL) { - return ERR_NOT_FOUND; - } - // TODO(tannewt): Should we flush here? - return ERR_NONE; -} - -/** - * \brief Inquiry whether Disk is writable. ERR_DENIED if it is not writable. - * ERR_NONE if it is. ERR_NOT_FOUND if its missing. - * \param[in] lun logic unit number - * \return Operation status. - */ -int32_t usb_msc_disk_is_writable(uint8_t lun) { - if (lun > 1) { - return ERR_NOT_FOUND; - } - - fs_user_mount_t* vfs = get_vfs(lun); - if (vfs == NULL) { - return ERR_NOT_FOUND; - } - if (vfs->writeblocks[0] == MP_OBJ_NULL || - (vfs->flags & FSUSER_USB_WRITABLE) == 0) { - return ERR_DENIED; - } - return ERR_NONE; -} - -/** - * \brief Inquiry whether Disk is ready - * \param[in] lun logic unit number - * \return Operation status. - */ -int32_t usb_msc_disk_is_ready(uint8_t lun) { - if (lun > 1) { - return ERR_NOT_FOUND; - } - - fs_user_mount_t* current_mount = get_vfs(lun); - if (current_mount == NULL) { - return ERR_NOT_FOUND; - } - return ERR_NONE; -} - -/** - * \brief Callback invoked when inquiry data command received - * \param[in] lun logic unit number - * \return Operation status. - */ -uint8_t *usb_msc_inquiry_info(uint8_t lun) { - if (lun > 1) { - return NULL; - } else { - for (uint8_t i = 0; i < 36; i++) { - inquiry_info[lun][i] = 0; - } - inquiry_info[lun][0] = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS; - // connected, direct access - inquiry_info[lun][1] = SCSI_INQ_RMB; // removable medium - inquiry_info[lun][2] = SCSI_INQ_VER_SPC; // SBC version of SCSI primary commands - inquiry_info[lun][3] = SCSI_INQ_RSP_SPC2;// SPC-2 response format - inquiry_info[lun][4] = 31; // 31 bytes following - return &inquiry_info[lun][0]; - } -} - -/** - * \brief Callback invoked when read format capacities command received - * \param[in] lun logic unit number - */ -uint8_t *usb_msc_get_capacity(uint8_t lun) { - if (lun > 1) { - return NULL; - } else { - fs_user_mount_t * vfs = get_vfs(lun); - uint32_t last_valid_sector = 0; - uint32_t sector_size = 0; - if (vfs == NULL || - disk_ioctl(vfs, GET_SECTOR_COUNT, &last_valid_sector) != RES_OK || - disk_ioctl(vfs, GET_SECTOR_SIZE, §or_size) != RES_OK) { - return NULL; - } - // Subtract one from the sector count to get the last valid sector. - last_valid_sector--; - - format_capa[lun][0] = (uint8_t)(last_valid_sector >> 24); - format_capa[lun][1] = (uint8_t)(last_valid_sector >> 16); - format_capa[lun][2] = (uint8_t)(last_valid_sector >> 8); - format_capa[lun][3] = (uint8_t)(last_valid_sector >> 0); - format_capa[lun][4] = (uint8_t)(sector_size >> 24); - format_capa[lun][5] = (uint8_t)(sector_size >> 16); - format_capa[lun][6] = (uint8_t)(sector_size >> 8); - format_capa[lun][7] = (uint8_t)(sector_size >> 0); - - // 8 byte response. First 4 bytes are last block address. Second 4 - // bytes are sector size. - return &format_capa[lun][0]; - } -} - -// USB transfer state. -volatile bool usb_busy; -volatile bool active_read; -volatile bool active_write; -volatile uint8_t active_lun; -volatile uint32_t active_addr; -volatile uint32_t active_nblocks; -volatile bool sector_loaded; -COMPILER_ALIGNED(4) uint8_t sector_buffer[512]; - -/** - * \brief Callback invoked when a new read blocks command received - * \param[in] lun logic unit number - * \param[in] addr start address of disk to be read - * \param[in] nblocks block amount to be read - * \return Operation status. - */ -int32_t usb_msc_new_read(uint8_t lun, uint32_t addr, uint32_t nblocks) { - if (lun > 1) { - return ERR_NOT_FOUND; - } - - // Store transfer info so we can service it in the "background". - active_lun = lun; - active_addr = addr; - active_nblocks = nblocks; - active_read = true; - - return ERR_NONE; -} - -/** - * \brief Callback invoked when a new write blocks command received - * \param[in] lun logic unit number - * \param[in] addr start address of disk to be written - * \param[in] nblocks block amount to be written - * \return Operation status. - */ -int32_t usb_msc_new_write(uint8_t lun, uint32_t addr, uint32_t nblocks) { - if (lun > 1) { - return ERR_NOT_FOUND; - } - - fs_user_mount_t * vfs = get_vfs(lun); - // This is used to determine the writeability of the disk from USB. - if (vfs == NULL) { - return ERR_NOT_FOUND; - } - if (vfs->writeblocks[0] == MP_OBJ_NULL || - (vfs->flags & FSUSER_USB_WRITABLE) == 0) { - return ERR_DENIED; - } - - // Store transfer info so we can service it in the "background". - active_lun = lun; - active_addr = addr; - active_nblocks = nblocks; - active_write = true; - sector_loaded = false; - - // Return ERR_DENIED when the file system is read-only to the USB host. - - return ERR_NONE; -} - -/** - * \brief Callback invoked when a blocks transfer is done - * \param[in] lun logic unit number - * \return Operation status. - */ -int32_t usb_msc_xfer_done(uint8_t lun) { - if (lun > 1) { - return ERR_DENIED; - } - - CRITICAL_SECTION_ENTER(); - if (active_read) { - active_addr += 1; - active_nblocks--; - if (active_nblocks == 0) { - active_read = false; - } - } - - if (active_write) { - sector_loaded = true; - } - usb_busy = false; - CRITICAL_SECTION_LEAVE(); - - return ERR_NONE; -} - -// The start_read callback begins a read transaction which we accept -// but delay our response until the "main thread" calls -// usb_msc_background. Once it does, we read immediately from the -// drive into our cache and trigger the USB DMA to output the -// sector. Once the sector is transmitted, xfer_done will be called. -void usb_msc_background(void) { - // Check USB busy first because we never want to queue another transfer if it is. Checking - // active_read or active_write first leaves the possibility that they are true, an xfer done - // interrupt occurs (setting them false), turning off usb_busy and causing us to queue a - // spurious transfer. - if (usb_busy) { - return; - } - if (active_read) { - fs_user_mount_t * vfs = get_vfs(active_lun); - disk_read(vfs, sector_buffer, active_addr, 1); - CRITICAL_SECTION_ENTER(); - int32_t result = mscdf_xfer_blocks(true, sector_buffer, 1); - usb_busy = result == ERR_NONE; - CRITICAL_SECTION_LEAVE(); - } - if (active_write) { - if (sector_loaded) { - fs_user_mount_t * vfs = get_vfs(active_lun); - disk_write(vfs, sector_buffer, active_addr, 1); - // Since by getting here we assume the mount is read-only to - // MicroPython let's update the cached FatFs sector if it's the one - // we just wrote. - #if _MAX_SS != _MIN_SS - if (vfs->ssize == FILESYSTEM_BLOCK_SIZE) { - #else - // The compiler can optimize this away. - if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) { - #endif - if (active_addr == vfs->fatfs.winsect && active_addr > 0) { - memcpy(vfs->fatfs.win, - sector_buffer, - FILESYSTEM_BLOCK_SIZE); - } - } - sector_loaded = false; - active_addr += 1; - active_nblocks--; - } - // Load more blocks from USB if they are needed. - if (active_nblocks > 0) { - // Turn off interrupts because with them on, - // usb_msc_xfer_done could be called before we update - // usb_busy. If that happened, we'd overwrite the fact that - // the transfer actually already finished. - CRITICAL_SECTION_ENTER(); - int32_t result = mscdf_xfer_blocks(false, sector_buffer, 1); - usb_busy = result == ERR_NONE; - CRITICAL_SECTION_LEAVE(); - } else { - mscdf_xfer_blocks(false, NULL, 0); - active_write = false; - // This write is complete, start the autoreload clock. - autoreload_start(); - } - } -} diff --git a/ports/atmel-samd/usb_mass_storage.h b/ports/atmel-samd/usb_mass_storage.h deleted file mode 100644 index 767a6779c..000000000 --- a/ports/atmel-samd/usb_mass_storage.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * 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. - */ - -// This adapts the ASF4 USB mass storage API to MicroPython's VFS API so we can -// expose all VFS block devices as Lun's over USB mass storage control. - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H - -#include - -// "background" task that actually manages loading to and from the file systems. -void usb_msc_background(void); - -// Callbacks that hook into ASF4's USB stack. -int32_t usb_msc_disk_eject(uint8_t lun); -int32_t usb_msc_disk_is_writable(uint8_t lun); -int32_t usb_msc_disk_is_ready(uint8_t lun); -int32_t usb_msc_new_read(uint8_t lun, uint32_t addr, uint32_t nblocks); -int32_t usb_msc_new_write(uint8_t lun, uint32_t addr, uint32_t nblocks); -int32_t usb_msc_xfer_done(uint8_t lun); -uint8_t *usb_msc_inquiry_info(uint8_t lun); -uint8_t *usb_msc_get_capacity(uint8_t lun); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_USB_MASS_STORAGE_H diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 3b6cc1fb4..03d5a65cb 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -119,7 +119,6 @@ SRC_COMMON_HAL = \ multiterminal/__init__.c \ neopixel_write/__init__.c \ os/__init__.c \ - storage/__init__.c \ time/__init__.c \ board/__init__.c @@ -147,7 +146,6 @@ SRC_SHARED_MODULE = \ multiterminal/__init__.c \ os/__init__.c \ random/__init__.c \ - storage/__init__.c \ struct/__init__.c SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index eca3f525d..435f2c5cd 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -162,7 +162,6 @@ extern const struct _mp_obj_module_t esp_module; extern const struct _mp_obj_module_t network_module; extern const struct _mp_obj_module_t os_module; extern const struct _mp_obj_module_t random_module; -extern const struct _mp_obj_module_t storage_module; extern const struct _mp_obj_module_t struct_module; extern const struct _mp_obj_module_t mp_module_lwip; extern const struct _mp_obj_module_t mp_module_machine; @@ -194,7 +193,6 @@ extern const struct _mp_obj_module_t neopixel_write_module; { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 25ddebc57..8d0d6d000 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -29,6 +29,10 @@ FROZEN_MPY_DIR = freeze # include py core make definitions include ../../py/py.mk +ifneq ($(MCU_SUB_VARIANT),nrf52840) +USB = FALSE +endif + include $(TOP)/supervisor/supervisor.mk FATFS_DIR = lib/oofatfs @@ -51,7 +55,7 @@ INC += -I./bluetooth INC += -I./peripherals INC += -I../../lib/mp-readline INC += -I../../lib/tinyusb/src -INC += -I./usb +INC += -I../../supervisor/shared/usb NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET @@ -68,6 +72,9 @@ LDFLAGS += -Xlinker -Map=$(@:.elf=.map) LDFLAGS += -mthumb -mabi=aapcs -T $(LD_FILE) -L boards/ LDFLAGS += -Wl,--gc-sections +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 + #Debugging/Optimization ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ @@ -94,10 +101,16 @@ SRC_NRFX = $(addprefix nrfx/,\ drivers/src/nrfx_uarte.c \ ) +ifdef EXTERNAL_FLASH_DEVICES + ifeq ($(QSPI_FLASH_FILESYSTEM),1) + SRC_NRFX += nrfx/drivers/src/nrfx_qspi.c + endif +endif + + SRC_C += \ background.c \ fatfs_port.c \ - internal_flash.c \ mphalport.c \ tick.c \ board_busses.c \ @@ -147,7 +160,6 @@ SRC_COMMON_HAL += \ pulseio/PulseIn.c \ pulseio/PulseOut.c \ pulseio/__init__.c \ - storage/__init__.c \ supervisor/Runtime.c \ supervisor/__init__.c \ time/__init__.c \ @@ -185,14 +197,9 @@ SRC_BINDINGS_ENUMS += \ bleio/UUIDType.c endif -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - SRC_SHARED_MODULE = \ os/__init__.c \ random/__init__.c \ - storage/__init__.c \ struct/__init__.c \ gamepad/__init__.c \ gamepad/GamePad.c \ @@ -201,44 +208,36 @@ SRC_SHARED_MODULE = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ + storage/__init__.c # uheap/__init__.c \ ustack/__init__.c -SRC_SHARED_BINDINGS = \ - struct/__init__.c \ - gamepad/__init__.c \ - gamepad/GamePad.c \ - bitbangio/__init__.c \ - bitbangio/I2C.c \ - bitbangio/SPI.c \ - bitbangio/OneWire.c \ - random/__init__.c \ - # USB source files for nrf52840 ifeq ($(MCU_SUB_VARIANT),nrf52840) SRC_C += \ - usb/usb.c \ - usb/usb_msc_flash.c \ - usb/usb_desc.c \ lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c \ lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c \ lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/control.c \ lib/tinyusb/src/device/usbd.c \ lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/hid/hid_device.c \ lib/tinyusb/src/tusb.c \ -SRC_COMMON_HAL += \ +SRC_SHARED_MODULE += \ usb_hid/__init__.c \ usb_hid/Device.c \ endif +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_BINDINGS)) \ +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) SRC_S = supervisor/cpu.s @@ -346,9 +345,10 @@ dfu-gen: $(BUILD)/dfu-package.zip $(BUILD)/dfu-package.zip: $(BUILD)/$(OUTPUT_FILENAME).hex $(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip +# You must have $^ here because it deduplicates entries in $(OBJ) $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ) $(ECHO) "LINK $@" - $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(CC) $(LDFLAGS) -o $@ $^ -Wl,--start-group $(LIBS) -Wl,--end-group $(Q)$(SIZE) $@ # List of sources for qstr extraction diff --git a/ports/nrf/README.md b/ports/nrf/README.md index 4bd865400..34e58cb78 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -61,7 +61,7 @@ To build and flash issue the following command inside the ports/nrf/ folder: First prepare the bluetooth folder by downloading Bluetooth LE stacks and headers: - ./drivers/bluetooth/download_ble_stack.sh + ./bluetooth/download_ble_stack.sh If the Bluetooth stacks has been downloaded, compile the target with the following command: diff --git a/ports/nrf/background.c b/ports/nrf/background.c index d19604f68..f614b6bd0 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -24,11 +24,12 @@ * THE SOFTWARE. */ -#include "tusb.h" +#ifdef NRF52840 +#include "supervisor/usb.h" +#endif void run_background_tasks(void) { -#ifdef NRF52840_XXAA - tusb_task(); - tud_cdc_write_flush(); -#endif + #ifdef NRF52840 + usb_background(); + #endif } diff --git a/ports/nrf/board_busses.c b/ports/nrf/board_busses.c index 91f0def6d..6d5cbd041 100644 --- a/ports/nrf/board_busses.c +++ b/ports/nrf/board_busses.c @@ -30,8 +30,8 @@ #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" -#include "mpconfigboard.h" #include "nrf/pins.h" +#include "py/mpconfig.h" #include "py/runtime.h" #if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL) diff --git a/ports/nrf/boards/feather_nrf52840_express/board.c b/ports/nrf/boards/feather_nrf52840_express/board.c index a6d050fce..4421970ee 100644 --- a/ports/nrf/boards/feather_nrf52840_express/board.c +++ b/ports/nrf/boards/feather_nrf52840_express/board.c @@ -25,10 +25,8 @@ */ #include "boards/board.h" -#include "usb.h" void board_init(void) { - usb_init(); } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index bd6d4b244..68914c626 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -25,6 +25,8 @@ * THE SOFTWARE. */ +#include "nrfx/hal/nrf_gpio.h" + #define FEATHER52840 #define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express" @@ -33,12 +35,12 @@ #define MICROPY_HW_NEOPIXEL (&pin_P0_13) -#define MICROPY_QSPI_DATA0 (&pin_P1_09) -#define MICROPY_QSPI_DATA1 (&pin_P0_11) -#define MICROPY_QSPI_DATA2 (&pin_P0_12) -#define MICROPY_QSPI_DATA3 (&pin_P0_14) -#define MICROPY_QSPI_SCK (&pin_P0_08) -#define MICROPY_QSPI_CS (&pin_P1_08) +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 9) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 11) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 12) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 14) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 8) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 @@ -49,14 +51,7 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -// TODO #include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -#define EXTERNAL_FLASH_DEVICES GD25Q16C - -#define EXTERNAL_FLASH_QSPI_DUAL - -// TODO include "external_flash/external_flash.h" +#define EXTERNAL_FLASH_QSPI_DUAL (1) #define BOARD_HAS_CRYSTAL 1 diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk index caf580ec4..f03109319 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk @@ -1,3 +1,8 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "Feather nRF52840 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + MCU_SERIES = m4 MCU_VARIANT = nrf52 MCU_SUB_VARIANT = nrf52840 @@ -14,3 +19,7 @@ else endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q64C" diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c index a6d050fce..4421970ee 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c @@ -25,10 +25,8 @@ */ #include "boards/board.h" -#include "usb.h" void board_init(void) { - usb_init(); } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h index b33fb2dd6..40b6487ec 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h @@ -25,18 +25,20 @@ * THE SOFTWARE. */ +#include "nrfx/hal/nrf_gpio.h" + #define MAKERDIARYNRF52840MDK #define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDK" -#define MICROPY_QSPI_DATA0 (&pin_P1_05) -#define MICROPY_QSPI_DATA1 (&pin_P1_04) -#define MICROPY_QSPI_DATA2 (&pin_P1_02) -#define MICROPY_QSPI_DATA3 (&pin_P1_01) -#define MICROPY_QSPI_SCK (&pin_P1_03) -#define MICROPY_QSPI_CS (&pin_P1_06) +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 5) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 4) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 2) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 1) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 3) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 @@ -47,17 +49,6 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -// TODO #include "external_flash/devices.h" - -#define EXTERNAL_FLASH_DEVICE_COUNT 1 -// Datasheet for when this is implemented: -// http://www.mxic.com.tw/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf -#define EXTERNAL_FLASH_DEVICES MX25R6435F - -#define EXTERNAL_FLASH_QSPI_DUAL - -// TODO include "external_flash/external_flash.h" - #define BOARD_HAS_CRYSTAL 0 #define DEFAULT_UART_BUS_RX (&pin_P0_19) diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk index caf580ec4..84dff0bc4 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk @@ -1,3 +1,8 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "nRF52840-MDK" +USB_MANUFACTURER = "makerdiary" + MCU_SERIES = m4 MCU_VARIANT = nrf52 MCU_SUB_VARIANT = nrf52840 @@ -14,3 +19,7 @@ else endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/pca10056/board.c b/ports/nrf/boards/pca10056/board.c index a6d050fce..4421970ee 100644 --- a/ports/nrf/boards/pca10056/board.c +++ b/ports/nrf/boards/pca10056/board.c @@ -25,10 +25,8 @@ */ #include "boards/board.h" -#include "usb.h" void board_init(void) { - usb_init(); } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h index 00a73005c..83c3f66c1 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.h +++ b/ports/nrf/boards/pca10056/mpconfigboard.h @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "nrfx/hal/nrf_gpio.h" + #define MICROPY_HW_BOARD_NAME "PCA10056 nRF52840-DK" #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "nRF52840-DK" @@ -40,3 +42,24 @@ #define DEFAULT_UART_BUS_RX (&pin_P1_01) #define DEFAULT_UART_BUS_TX (&pin_P1_02) + +// Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration. +// A pin config is valid if it is defined and its value is not 0xFF. +// Quad mode: If all DATA0 --> DATA3 are valid +// Dual mode: If DATA0 and DATA1 are valid while either DATA2 and/or DATA3 are invalid +// Single mode: If only DATA0 is valid +#ifdef QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#ifdef SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif diff --git a/ports/nrf/boards/pca10056/mpconfigboard.mk b/ports/nrf/boards/pca10056/mpconfigboard.mk index caf580ec4..49c708cff 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.mk +++ b/ports/nrf/boards/pca10056/mpconfigboard.mk @@ -1,3 +1,8 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "PCA10056" +USB_MANUFACTURER = "Nordic Semiconductor" + MCU_SERIES = m4 MCU_VARIANT = nrf52 MCU_SUB_VARIANT = nrf52840 @@ -14,3 +19,7 @@ else endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/pca10059/board.c b/ports/nrf/boards/pca10059/board.c index cbb4ef3b6..4421970ee 100644 --- a/ports/nrf/boards/pca10059/board.c +++ b/ports/nrf/boards/pca10059/board.c @@ -24,14 +24,9 @@ * THE SOFTWARE. */ -#include -#include #include "boards/board.h" -#include "nrfx.h" -#include "usb.h" void board_init(void) { - usb_init(); } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/pca10059/mpconfigboard.mk b/ports/nrf/boards/pca10059/mpconfigboard.mk index f399927fd..030c9a823 100644 --- a/ports/nrf/boards/pca10059/mpconfigboard.mk +++ b/ports/nrf/boards/pca10059/mpconfigboard.mk @@ -1,3 +1,8 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "PCA10059" +USB_MANUFACTURER = "Nordic Semiconductor" + MCU_SERIES = m4 MCU_VARIANT = nrf52 MCU_SUB_VARIANT = nrf52840 diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index f094b7f24..19bd4d1ba 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -59,12 +59,30 @@ STATIC spim_peripheral_t spim_peripherals[] = { #endif }; +STATIC bool never_reset[4]; + void spi_reset(void) { for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { + if (never_reset[i]) { + continue; + } nrf_spim_disable(spim_peripherals[i].spim.p_reg); } } +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { + if (self->spim_peripheral == &spim_peripherals[i]) { + never_reset[i] = true; + + never_reset_pin_number(self->clock_pin_number); + never_reset_pin_number(self->MOSI_pin_number); + never_reset_pin_number(self->MISO_pin_number); + break; + } + } +} + // Convert frequency to clock-speed-dependent value. Choose the next lower baudrate if in between // available baudrates. static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) { diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index b9e79381a..516a7747d 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -27,7 +27,7 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/busio/UART.h" -#include "mpconfigport.h" +#include "py/mpconfig.h" #include "py/gc.h" #include "py/mperrno.h" #include "py/runtime.h" diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c index f05cf568f..0836962c6 100644 --- a/ports/nrf/common-hal/digitalio/DigitalInOut.c +++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c @@ -30,6 +30,11 @@ #include "nrf_gpio.h" +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + never_reset_pin_number(self->pin->number); +} + digitalinout_result_t common_hal_digitalio_digitalinout_construct( digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { claim_pin(pin); diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index 7a069eeda..0522bfef3 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -45,13 +45,18 @@ bool speaker_enable_in_use; // Bit mask of claimed pins on each of up to two ports. nrf52832 has one port; nrf52840 has two. STATIC uint32_t claimed_pins[GPIO_COUNT]; +STATIC uint32_t never_reset_pins[GPIO_COUNT]; void reset_all_pins(void) { + return; for (size_t i = 0; i < GPIO_COUNT; i++) { - claimed_pins[i] = 0; + claimed_pins[i] = never_reset_pins[i]; } for (uint32_t pin = 0; pin < NUMBER_OF_PINS; ++pin) { + if (!(never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin)))) { + continue; + } nrf_gpio_cfg_default(pin); } @@ -72,6 +77,7 @@ void reset_all_pins(void) { // Mark pin as free and return it to a quiescent state. void reset_pin_number(uint8_t pin_number) { + return; if (pin_number == NO_PIN) { return; } @@ -108,6 +114,11 @@ void reset_pin_number(uint8_t pin_number) { #endif } + +void never_reset_pin_number(uint8_t pin_number) { + never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number); +} + void claim_pin(const mcu_pin_obj_t* pin) { // Set bit in claimed_pins bitmask. claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number); diff --git a/ports/nrf/common-hal/microcontroller/Pin.h b/ports/nrf/common-hal/microcontroller/Pin.h index 2cdf440b5..61be8bc35 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.h +++ b/ports/nrf/common-hal/microcontroller/Pin.h @@ -44,6 +44,7 @@ void reset_all_pins(void); // need to store a full pointer. void reset_pin_number(uint8_t pin); void claim_pin(const mcu_pin_obj_t* pin); +void never_reset_pin_number(uint8_t pin_number); // Lower 5 bits of a pin number are the pin number in a port. // upper bits (just one bit for current chips) is port number. diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index 2ce3e8bf5..e4d9439c9 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -72,12 +72,7 @@ uint32_t common_hal_mcu_processor_get_frequency(void) { } void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { - - uint32_t* id_addresses[2] = {(uint32_t *) 0x060, (uint32_t *) 0x064}; - for (int i=0; i<2; i++) { - for (int k=0; k<4; k++) { - raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff; - } + ((uint32_t*) raw_id)[i] = NRF_FICR->DEVICEID[i]; } } diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index 950cc877d..3d6d266af 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -28,7 +28,7 @@ #include -#include "mpconfigport.h" +#include "py/mpconfig.h" #include "py/gc.h" #include "py/runtime.h" diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index 044c4d3a8..be5deca9f 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -28,7 +28,7 @@ #include -#include "mpconfigport.h" +#include "py/mpconfig.h" #include "nrf/pins.h" #include "nrf/timers.h" #include "py/gc.h" diff --git a/ports/nrf/common-hal/storage/__init__.c b/ports/nrf/common-hal/storage/__init__.c deleted file mode 100644 index 4ff5f0dac..000000000 --- a/ports/nrf/common-hal/storage/__init__.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 - -#include "py/mperrno.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/storage/__init__.h" -#include "supervisor/filesystem.h" - -extern volatile bool mp_msc_enabled; - -void common_hal_storage_remount(const char *mount_path, bool readonly) { - if (strcmp(mount_path, "/") != 0) { - mp_raise_OSError(MP_EINVAL); - } -} - -void common_hal_storage_erase_filesystem(void) { - filesystem_init(false, true); // Force a re-format. - common_hal_mcu_reset(); - // We won't actually get here, since we're resetting. -} diff --git a/ports/nrf/common-hal/usb_hid/Device.c b/ports/nrf/common-hal/usb_hid/Device.c deleted file mode 100644 index 6acb2717f..000000000 --- a/ports/nrf/common-hal/usb_hid/Device.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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 -#include "tick.h" -#include "common-hal/usb_hid/Device.h" -#include "py/runtime.h" -#include "shared-bindings/usb_hid/Device.h" -#include "supervisor/shared/translate.h" -#include "tusb.h" - -uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { - return self->usage_page; -} - -uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { - return self->usage; -} - -void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { - if (len != self->report_length) { - mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length); - } - - // Wait until interface is ready, timeout = 2 seconds - uint64_t end_ticks = ticks_ms + 2000; - while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { } - - if ( !tud_hid_generic_ready() ) { - mp_raise_msg(&mp_type_OSError, translate("USB Busy")); - } - - memcpy(self->report_buffer, report, len); - - if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) { - mp_raise_msg(&mp_type_OSError, translate("USB Error")); - } -} - -// Callbacks invoked when receive Get_Report request through control endpoint -uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { - // only support Input Report - if ( report_type != HID_REPORT_TYPE_INPUT ) return 0; - - // index is ID-1 - uint8_t idx = ( report_id ? (report_id-1) : 0 ); - - // fill buffer with current report - memcpy(buffer, usb_hid_devices[idx].report_buffer, reqlen); - return reqlen; -} - -// Callbacks invoked when receive Set_Report request through control endpoint -void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { - // index is ID-1 - uint8_t idx = ( report_id ? (report_id-1) : 0 ); - - if ( report_type == HID_REPORT_TYPE_OUTPUT ) { - // Check if it is Keyboard device - if ( (usb_hid_devices[idx].usage_page == HID_USAGE_PAGE_DESKTOP) && (usb_hid_devices[idx].usage == HID_USAGE_DESKTOP_KEYBOARD) ) { - // This is LED indicator (CapsLock, NumLock) - // TODO Light up some LED here - } - } -} diff --git a/ports/nrf/common-hal/usb_hid/Device.h b/ports/nrf/common-hal/usb_hid/Device.h deleted file mode 100644 index 612423715..000000000 --- a/ports/nrf/common-hal/usb_hid/Device.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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. - */ - -#ifndef COMMON_HAL_USB_HID_DEVICE_H -#define COMMON_HAL_USB_HID_DEVICE_H - -#include -#include - -#include "py/obj.h" - -#ifdef __cplusplus - extern "C" { -#endif - -// 1 to enable device, 0 to disable -#define USB_HID_DEVICE_KEYBOARD 1 -#define USB_HID_DEVICE_MOUSE 1 -#define USB_HID_DEVICE_CONSUMER 1 -#define USB_HID_DEVICE_SYS_CONTROL 1 -#define USB_HID_DEVICE_GAMEPAD 1 -#define USB_HID_DEVICE_DIGITIZER 0 // not supported yet - -enum { - USB_HID_REPORT_ID_UNUSED = 0, - -#if USB_HID_DEVICE_KEYBOARD - USB_HID_REPORT_ID_KEYBOARD, -#endif - -#if USB_HID_DEVICE_MOUSE - USB_HID_REPORT_ID_MOUSE, -#endif - -#if USB_HID_DEVICE_CONSUMER - USB_HID_REPORT_ID_CONSUMER, -#endif - -#if USB_HID_DEVICE_SYS_CONTROL - USB_HID_REPORT_ID_SYS_CONTROL, -#endif - -#if USB_HID_DEVICE_GAMEPAD - USB_HID_REPORT_ID_GAMEPAD, -#endif - -#if USB_HID_DEVICE_DIGITIZER - USB_HID_REPORT_ID_DIGITIZER, -#endif -}; - -#define USB_HID_NUM_DEVICES (USB_HID_DEVICE_KEYBOARD + USB_HID_DEVICE_MOUSE + USB_HID_DEVICE_CONSUMER + \ - USB_HID_DEVICE_SYS_CONTROL + USB_HID_DEVICE_GAMEPAD + USB_HID_DEVICE_DIGITIZER ) - -typedef struct { - mp_obj_base_t base; - uint8_t* report_buffer; - uint8_t report_id; - uint8_t report_length; - uint8_t usage_page; - uint8_t usage; -} usb_hid_device_obj_t; - - -extern usb_hid_device_obj_t usb_hid_devices[]; - -#ifdef __cplusplus - } -#endif - -#endif /* COMMON_HAL_USB_HID_DEVICE_H */ diff --git a/ports/nrf/common-hal/usb_hid/__init__.c b/ports/nrf/common-hal/usb_hid/__init__.c deleted file mode 100644 index 00fc8bd00..000000000 --- a/ports/nrf/common-hal/usb_hid/__init__.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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 "py/obj.h" -#include "py/mphal.h" -#include "py/runtime.h" - -#include "common-hal/usb_hid/Device.h" -#include "shared-bindings/usb_hid/Device.h" -#include "tusb.h" - -#define USB_HID_REPORT_LENGTH_KEYBOARD 8 -#define USB_HID_REPORT_LENGTH_MOUSE 4 -#define USB_HID_REPORT_LENGTH_CONSUMER 2 -#define USB_HID_REPORT_LENGTH_SYS_CONTROL 1 -#define USB_HID_REPORT_LENGTH_GAMEPAD 6 -#define USB_HID_REPORT_LENGTH_DIGITIZER 5 - -#if USB_HID_DEVICE_KEYBOARD -static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD]; -#endif - -#if USB_HID_DEVICE_MOUSE -static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE]; -#endif - -#if USB_HID_DEVICE_CONSUMER -static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER]; -#endif - -#if USB_HID_DEVICE_SYS_CONTROL -static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL]; -#endif - -#if USB_HID_DEVICE_GAMEPAD -static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD]; -#endif - -#if USB_HID_DEVICE_DIGITIZER -static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; -#endif - -usb_hid_device_obj_t usb_hid_devices[] = { -#if USB_HID_DEVICE_KEYBOARD - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = keyboard_report_buffer , - .report_id = USB_HID_REPORT_ID_KEYBOARD , - .report_length = USB_HID_REPORT_LENGTH_KEYBOARD , - .usage_page = HID_USAGE_PAGE_DESKTOP , - .usage = HID_USAGE_DESKTOP_KEYBOARD , - }, -#endif - -#if USB_HID_DEVICE_MOUSE - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = mouse_report_buffer , - .report_id = USB_HID_REPORT_ID_MOUSE , - .report_length = USB_HID_REPORT_LENGTH_MOUSE , - .usage_page = HID_USAGE_PAGE_DESKTOP , - .usage = HID_USAGE_DESKTOP_MOUSE , - }, -#endif - -#if USB_HID_DEVICE_CONSUMER - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = consumer_report_buffer , - .report_id = USB_HID_REPORT_ID_CONSUMER , - .report_length = USB_HID_REPORT_LENGTH_CONSUMER , - .usage_page = HID_USAGE_PAGE_CONSUMER , - .usage = HID_USAGE_CONSUMER_CONTROL , - }, -#endif - -#if USB_HID_DEVICE_SYS_CONTROL - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = sys_control_report_buffer , - .report_id = USB_HID_REPORT_ID_SYS_CONTROL , - .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL , - .usage_page = HID_USAGE_PAGE_DESKTOP , - .usage = HID_USAGE_DESKTOP_SYSTEM_CONTROL , - }, -#endif - -#if USB_HID_DEVICE_GAMEPAD - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = gamepad_report_buffer , - .report_id = USB_HID_REPORT_ID_GAMEPAD , - .report_length = USB_HID_REPORT_LENGTH_GAMEPAD , - .usage_page = HID_USAGE_PAGE_DESKTOP , - .usage = HID_USAGE_DESKTOP_GAMEPAD , - }, -#endif - -#if USB_HID_DEVICE_DIGITIZER - { - .base = { .type = &usb_hid_device_type } , - .report_buffer = digitizer_report_buffer , - .report_id = USB_HID_REPORT_ID_DIGITIZER , - .report_length = USB_HID_REPORT_LENGTH_DIGITIZER , - .usage_page = 0x0D , - .usage = 0x02 , - }, -#endif -}; - - -mp_obj_tuple_t common_hal_usb_hid_devices = { - .base = { - .type = &mp_type_tuple, - }, - .len = USB_HID_NUM_DEVICES, - .items = { -#if USB_HID_NUM_DEVICES >= 1 - (mp_obj_t) &usb_hid_devices[0], -#endif -#if USB_HID_NUM_DEVICES >= 2 - (mp_obj_t) &usb_hid_devices[1], -#endif -#if USB_HID_NUM_DEVICES >= 3 - (mp_obj_t) &usb_hid_devices[2], -#endif -#if USB_HID_NUM_DEVICES >= 4 - (mp_obj_t) &usb_hid_devices[3], -#endif -#if USB_HID_NUM_DEVICES >= 5 - (mp_obj_t) &usb_hid_devices[4], -#endif -#if USB_HID_NUM_DEVICES >= 6 - (mp_obj_t) &usb_hid_devices[5], -#endif - } -}; diff --git a/ports/nrf/internal_flash.c b/ports/nrf/internal_flash.c deleted file mode 100644 index 812ef4d3f..000000000 --- a/ports/nrf/internal_flash.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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 "internal_flash.h" - -#include -#include - -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "py/mphal.h" -#include "py/obj.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" -#include "supervisor/shared/rgb_led_status.h" - -#include "nrf_nvmc.h" - -#ifdef BLUETOOTH_SD -#include "nrf_sdm.h" -#endif - -// defined in linker -extern uint32_t __fatfs_flash_start_addr[]; -extern uint32_t __fatfs_flash_length[]; - -#define NO_CACHE 0xffffffff -#define FL_PAGE_SZ 4096 - -uint8_t _flash_cache[FL_PAGE_SZ] __attribute__((aligned(4))); -uint32_t _flash_page_addr = NO_CACHE; - - -/*------------------------------------------------------------------*/ -/* Internal Flash API - *------------------------------------------------------------------*/ -static inline uint32_t lba2addr(uint32_t block) { - return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE; -} - -void internal_flash_init(void) { - // Activity LED for flash writes. -#ifdef MICROPY_HW_LED_MSC - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_OUTPUT; - port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf); - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); -#endif -} - -uint32_t internal_flash_get_block_size(void) { - return FILESYSTEM_BLOCK_SIZE; -} - -uint32_t internal_flash_get_block_count(void) { - return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ; -} - -// TODO support flashing with SD enabled -void internal_flash_flush(void) { - if (_flash_page_addr == NO_CACHE) return; - - // Skip if data is the same - if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) { -// _is_flashing = true; - nrf_nvmc_page_erase(_flash_page_addr); - nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); - } - - _flash_page_addr = NO_CACHE; -} - -mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - uint32_t src = lba2addr(block); - memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks); - return 0; // success -} - -mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { - -#ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, true); -#endif - - while (num_blocks) { - uint32_t const addr = lba2addr(lba); - uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1); - - uint32_t count = 8 - (lba % 8); // up to page boundary - count = MIN(num_blocks, count); - - if (page_addr != _flash_page_addr) { - internal_flash_flush(); - - // writing previous cached data, skip current data until flashing is done - // tinyusb stack will invoke write_block() with the same parameters later on - // if ( _is_flashing ) return; - - _flash_page_addr = page_addr; - memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ); - } - - memcpy(_flash_cache + (addr & (FL_PAGE_SZ - 1)), src, count * FILESYSTEM_BLOCK_SIZE); - - // adjust for next run - lba += count; - src += count * FILESYSTEM_BLOCK_SIZE; - num_blocks -= count; - } - -#ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); -#endif - - return 0; // success -} - -/******************************************************************************/ -// MicroPython bindings -// -// Expose the flash as an object with the block protocol. - -// there is a singleton Flash object -STATIC const mp_obj_base_t internal_flash_obj = {&internal_flash_type}; - -STATIC mp_obj_t internal_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); - - // return singleton object - return (mp_obj_t)&internal_flash_obj; -} - -STATIC mp_obj_t internal_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); - mp_uint_t ret = internal_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_readblocks_obj, internal_flash_obj_readblocks); - -STATIC mp_obj_t internal_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - mp_uint_t ret = internal_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); - return MP_OBJ_NEW_SMALL_INT(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_writeblocks_obj, internal_flash_obj_writeblocks); - -STATIC mp_obj_t internal_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { - mp_int_t cmd = mp_obj_get_int(cmd_in); - switch (cmd) { - case BP_IOCTL_INIT: internal_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_DEINIT: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly - case BP_IOCTL_SYNC: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_count()); - case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_size()); - default: return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_ioctl_obj, internal_flash_obj_ioctl); - -STATIC const mp_rom_map_elem_t internal_flash_obj_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&internal_flash_obj_readblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&internal_flash_obj_writeblocks_obj) }, - { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&internal_flash_obj_ioctl_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(internal_flash_obj_locals_dict, internal_flash_obj_locals_dict_table); - -const mp_obj_type_t internal_flash_type = { - { &mp_type_type }, - .name = MP_QSTR_InternalFlash, - .make_new = internal_flash_obj_make_new, - .locals_dict = (mp_obj_t)&internal_flash_obj_locals_dict, -}; - -/*------------------------------------------------------------------*/ -/* Flash API - *------------------------------------------------------------------*/ - -void flash_init_vfs(fs_user_mount_t *vfs) { - vfs->base.type = &mp_fat_vfs_type; - vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; - vfs->fatfs.drv = vfs; - -// vfs->fatfs.part = 1; // flash filesystem lives on first partition - vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj; - vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj; - vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version - - vfs->writeblocks[0] = (mp_obj_t)&internal_flash_obj_writeblocks_obj; - vfs->writeblocks[1] = (mp_obj_t)&internal_flash_obj; - vfs->writeblocks[2] = (mp_obj_t)internal_flash_write_blocks; // native version - - vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj; - vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj; -} - -void flash_flush(void) { - internal_flash_flush(); -} diff --git a/ports/nrf/internal_flash.h b/ports/nrf/internal_flash.h deleted file mode 100644 index 3811815e2..000000000 --- a/ports/nrf/internal_flash.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H -#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H - -#include -#include - -#include "mpconfigport.h" - -#define FLASH_ROOT_POINTERS - -#define FLASH_PAGE_SIZE 0x1000 -#define CIRCUITPY_INTERNAL_NVM_SIZE 0 - -#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms -#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) - -void internal_flash_init(void); -uint32_t internal_flash_get_block_size(void); -uint32_t internal_flash_get_block_count(void); -void internal_flash_irq_handler(void); -void internal_flash_flush(void); - -// these return 0 on success, non-zero on error -mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); - -extern const struct _mp_obj_type_t internal_flash_type; - -struct _fs_user_mount_t; - -void flash_init_vfs(struct _fs_user_mount_t *vfs); -void flash_flush(void); - -#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 8b193fb59..c9c03427f 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -58,7 +58,7 @@ #define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_FATFS_RPATH (2) -#define MICROPY_FATFS_MULTI_PARTITION (0) +#define MICROPY_FATFS_MULTI_PARTITION (1) #define MICROPY_FATFS_NUM_PERSISTENT (1) //#define MICROPY_FATFS_MAX_SS (4096) @@ -216,9 +216,12 @@ extern const struct _mp_obj_module_t bleio_module; #define MP_STATE_PORT MP_STATE_VM +#include "supervisor/flash_root_pointers.h" + #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ mp_obj_t gamepad_singleton; \ + FLASH_ROOT_POINTERS \ // We need to provide a declaration/definition of alloca() #include diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 17304b783..f43e29fce 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -5,3 +5,4 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz INTERNAL_LIBM = (1) +USB_SERIAL_NUMBER_LENGTH = 16 diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index e9a8722c6..73f38bada 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -31,86 +31,6 @@ #include "py/mpstate.h" #include "py/gc.h" -#if (MICROPY_PY_BLE_NUS == 0) - -#if !defined( NRF52840_XXAA) -int mp_hal_stdin_rx_chr(void) { - uint8_t data; - nrfx_uarte_rx(&serial_instance, &data, 1); - return data; -} - -bool mp_hal_stdin_any(void) { - return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY); -} - -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { - if (len == 0) { - return; - } - - // EasyDMA can only access SRAM - uint8_t * tx_buf = (uint8_t*) str; - if ( !nrfx_is_in_ram(str) ) { - tx_buf = (uint8_t *) gc_alloc(len, false, false); - memcpy(tx_buf, str, len); - } - - nrfx_uarte_tx(&serial_instance, tx_buf, len); - - if ( !nrfx_is_in_ram(str) ) { - gc_free(tx_buf); - } -} - -#else - -#include "tusb.h" - -int mp_hal_stdin_rx_chr(void) { - for (;;) { - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - // if (reload_requested) { - // return CHAR_CTRL_D; - // } - - if (tud_cdc_available()) { - #ifdef MICROPY_HW_LED_RX - gpio_toggle_pin_level(MICROPY_HW_LED_RX); - #endif - return tud_cdc_read_char(); - } - } - - return 0; -} - -bool mp_hal_stdin_any(void) { - return tud_cdc_available() > 0; -} - -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { - - #ifdef MICROPY_HW_LED_TX - gpio_toggle_pin_level(MICROPY_HW_LED_TX); - #endif - - #ifdef CIRCUITPY_BOOT_OUTPUT_FILE - if (boot_output_file != NULL) { - UINT bytes_written = 0; - f_write(boot_output_file, str, len, &bytes_written); - } - #endif - - tud_cdc_write(str, len); -} - -#endif // USB - -#endif // MICROPY_PY_BLE_NUS - /*------------------------------------------------------------------*/ /* delay *------------------------------------------------------------------*/ @@ -129,4 +49,3 @@ void mp_hal_delay_ms(mp_uint_t delay) { // TODO(tannewt): Go to sleep for a little while while we wait. } } - diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index 69b8e6a0c..1d3085e2b 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -37,6 +37,9 @@ #define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_SPIM_MISO_PULL_CFG 1 +// QSPI +#define NRFX_QSPI_ENABLED 1 + // TWI aka. I2C; enable TWIM0 and TWIM1 (no conflict with SPIM choices) #define NRFX_TWIM_ENABLED 1 #define NRFX_TWIM0_ENABLED 1 diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c index 0027d526f..7f7a003d3 100644 --- a/ports/nrf/peripherals/nrf/timers.c +++ b/ports/nrf/peripherals/nrf/timers.c @@ -31,7 +31,7 @@ #include "nrfx.h" #include "nrfx_timer.h" -#include "mpconfigport.h" +#include "py/mpconfig.h" #include "py/runtime.h" STATIC nrfx_timer_t nrfx_timers[] = { diff --git a/ports/nrf/supervisor/filesystem.c b/ports/nrf/supervisor/filesystem.c deleted file mode 100644 index b6611417d..000000000 --- a/ports/nrf/supervisor/filesystem.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * 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 "extmod/vfs_fat.h" -#include "lib/oofatfs/ff.h" -#include "lib/oofatfs/diskio.h" - -#include "py/mpstate.h" - -#include "internal_flash.h" - -static mp_vfs_mount_t _mp_vfs; -static fs_user_mount_t _internal_vfs; - - -void filesystem_init(bool create_allowed, bool force_create) { - // init the vfs object - fs_user_mount_t *int_vfs = &_internal_vfs; - int_vfs->flags = 0; - flash_init_vfs(int_vfs); - - // try to mount the flash - FRESULT res = f_mount(&int_vfs->fatfs); - - if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { - // no filesystem so create a fresh one - uint8_t working_buf[_MAX_SS]; - res = f_mkfs(&int_vfs->fatfs, FM_FAT | FM_SFD, 4096, working_buf, sizeof(working_buf)); - // Flush the new file system to make sure its repaired immediately. - flash_flush(); - if (res != FR_OK) { - return; - } - - // set label - f_setlabel(&int_vfs->fatfs, "CIRCUITPY"); - - // create lib folder - f_mkdir(&int_vfs->fatfs, "/lib"); - - flash_flush(); - } else if (res != FR_OK) { - return; - } - - mp_vfs_mount_t *mp_vfs = &_mp_vfs; - mp_vfs->str = "/"; - mp_vfs->len = 1; - mp_vfs->obj = MP_OBJ_FROM_PTR(int_vfs); - mp_vfs->next = NULL; - MP_STATE_VM(vfs_mount_table) = mp_vfs; - - // The current directory is used as the boot up directory. - // It is set to the internal flash filesystem by default. - MP_STATE_PORT(vfs_cur) = mp_vfs; -} - -void filesystem_flush(void) { - flash_flush(); -} - -void filesystem_writable_by_python(bool writable) { - fs_user_mount_t *vfs = &_internal_vfs; - - if (writable) { - vfs->flags |= FSUSER_USB_WRITABLE; - } else { - vfs->flags &= ~FSUSER_USB_WRITABLE; - } -} - -bool filesystem_present(void) { - return true; -} diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c new file mode 100644 index 000000000..a648afa17 --- /dev/null +++ b/ports/nrf/supervisor/internal_flash.c @@ -0,0 +1,121 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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 "supervisor/flash.h" + +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#include "nrf_nvmc.h" + +#ifdef BLUETOOTH_SD +#include "nrf_sdm.h" +#endif + +// defined in linker +extern uint32_t __fatfs_flash_start_addr[]; +extern uint32_t __fatfs_flash_length[]; + +#define NO_CACHE 0xffffffff +#define FL_PAGE_SZ 4096 + +uint8_t _flash_cache[FL_PAGE_SZ] __attribute__((aligned(4))); +uint32_t _flash_page_addr = NO_CACHE; + + +/*------------------------------------------------------------------*/ +/* Internal Flash API + *------------------------------------------------------------------*/ +static inline uint32_t lba2addr(uint32_t block) { + return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE; +} + +void supervisor_flash_init(void) { +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ; +} + +// TODO support flashing with SD enabled +void supervisor_flash_flush(void) { + if (_flash_page_addr == NO_CACHE) return; + + // Skip if data is the same + if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) { +// _is_flashing = true; + nrf_nvmc_page_erase(_flash_page_addr); + nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t)); + } + + _flash_page_addr = NO_CACHE; +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + uint32_t src = lba2addr(block); + memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks); + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { + while (num_blocks) { + uint32_t const addr = lba2addr(lba); + uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1); + + uint32_t count = 8 - (lba % 8); // up to page boundary + count = MIN(num_blocks, count); + + if (page_addr != _flash_page_addr) { + supervisor_flash_flush(); + + // writing previous cached data, skip current data until flashing is done + // tinyusb stack will invoke write_block() with the same parameters later on + // if ( _is_flashing ) return; + + _flash_page_addr = page_addr; + memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ); + } + + memcpy(_flash_cache + (addr & (FL_PAGE_SZ - 1)), src, count * FILESYSTEM_BLOCK_SIZE); + + // adjust for next run + lba += count; + src += count * FILESYSTEM_BLOCK_SIZE; + num_blocks -= count; + } + + return 0; // success +} diff --git a/ports/nrf/supervisor/internal_flash.h b/ports/nrf/supervisor/internal_flash.h new file mode 100644 index 000000000..adcb9bbc2 --- /dev/null +++ b/ports/nrf/supervisor/internal_flash.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#define FLASH_ROOT_POINTERS + +#define FLASH_PAGE_SIZE 0x1000 +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H diff --git a/ports/nrf/supervisor/internal_flash_root_pointers.h b/ports/nrf/supervisor/internal_flash_root_pointers.h new file mode 100644 index 000000000..cc6074585 --- /dev/null +++ b/ports/nrf/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index f98b05f5a..fcb3ae55c 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -89,6 +89,13 @@ void reset_port(void) { reset_all_pins(); } +void reset_to_bootloader(void) { + enum { DFU_MAGIC_SERIAL = 0x4e }; + + NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL; + NVIC_SystemReset(); +} + void HardFault_Handler(void) { diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c new file mode 100644 index 000000000..24b06c420 --- /dev/null +++ b/ports/nrf/supervisor/qspi_flash.c @@ -0,0 +1,146 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "py/mpconfig.h" // for EXTERNAL_FLASH_QSPI_DUAL +#include "nrfx_qspi.h" + +#include "shared-bindings/microcontroller/__init__.h" + +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/qspi_flash.h" + +bool spi_flash_command(uint8_t command) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = 0, + .length = 0, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false + }; + cinstr_cfg.opcode = command; + cinstr_cfg.length = 1; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + return true; +} + +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = command, + .length = length + 1, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false + }; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response); + return true; +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = command, + .length = length + 1, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false // We do this manually. + }; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL); + return true; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + if (command != CMD_SECTOR_ERASE) { + return false; + } + return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS; +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + nrfx_qspi_read(data, length, address); + return true; +} + +void spi_flash_init(void) { + // Init QSPI flash + nrfx_qspi_config_t qspi_cfg = { + .xip_offset = 0, + .pins = { + .sck_pin = MICROPY_QSPI_SCK, + .csn_pin = MICROPY_QSPI_CS, + .io0_pin = MICROPY_QSPI_DATA0, + .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, + + }, + .prot_if = { + .readoc = NRF_QSPI_READOC_FASTREAD, + .writeoc = NRF_QSPI_WRITEOC_PP, + .addrmode = NRF_QSPI_ADDRMODE_24BIT, + .dpmconfig = false + }, + .phy_if = { + .sck_freq = NRF_QSPI_FREQ_32MDIV16, + .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns + .spi_mode = NRF_QSPI_MODE_0, + .dpmen = false + }, + .irq_priority = 7, + }; + +#if EXTERNAL_FLASH_QSPI_DUAL + qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; + qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O; + qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O; +#else + qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; + qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2; + qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3; + qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO; + qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO; +#endif + + // No callback for blocking API + nrfx_qspi_init(&qspi_cfg, NULL, NULL); +} + +void spi_flash_init_device(const external_flash_device* device) { + check_quad_enable(device); + + // TODO(tannewt): Adjust the speed for the found device. +} diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index c7744fd79..6fd89eb3e 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,9 +26,12 @@ #include "py/mphal.h" +#include "supervisor/serial.h" + #if (MICROPY_PY_BLE_NUS == 1) #include "ble_uart.h" #else +#include #include "nrf_gpio.h" #include "nrfx_uarte.h" #endif @@ -89,39 +92,36 @@ bool serial_connected(void) { } char serial_read(void) { - return (char) mp_hal_stdin_rx_chr(); + uint8_t data; + nrfx_uarte_rx(&serial_instance, &data, 1); + return data; } bool serial_bytes_available(void) { - return mp_hal_stdin_any(); + return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY); } -void serial_write(const char *text) { - mp_hal_stdout_tx_str(text); -} - -#else - -#include "tusb.h" - -void serial_init(void) { - // usb is already initialized in board_init() +void serial_write(const char* text) { + serial_write_substring(text, strlen(text)); } -bool serial_connected(void) { - return tud_cdc_connected(); -} +void serial_write_substring(const char *text, uint32_t len) { + if (len == 0) { + return; + } -char serial_read(void) { - return (char) tud_cdc_read_char(); -} + // EasyDMA can only access SRAM + uint8_t * tx_buf = (uint8_t*) text; + if ( !nrfx_is_in_ram(text) ) { + tx_buf = (uint8_t *) m_malloc(len, false); + memcpy(tx_buf, text, len); + } -bool serial_bytes_available(void) { - return tud_cdc_available() > 0; -} + nrfx_uarte_tx(&serial_instance, tx_buf, len); -void serial_write(const char* text) { - tud_cdc_write(text, strlen(text)); + if ( !nrfx_is_in_ram(text) ) { + m_free(tx_buf); + } } #endif diff --git a/ports/nrf/supervisor/usb.c b/ports/nrf/supervisor/usb.c new file mode 100644 index 000000000..a67c9311a --- /dev/null +++ b/ports/nrf/supervisor/usb.c @@ -0,0 +1,83 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "nrfx.h" +#include "nrfx_power.h" +#include "tick.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +/* tinyusb function that handles power event (detected, ready, removed) + * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. + */ +extern void tusb_hal_nrf_power_event(uint32_t event); + +void init_usb_hardware(void) { + + // USB power may already be ready at this time -> no event generated + // We need to invoke the handler based on the status initially + uint32_t usb_reg; + +#ifdef SOFTDEVICE_PRESENT + uint8_t sd_en = false; + (void) sd_softdevice_is_enabled(&sd_en); + + if ( sd_en ) { + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); + + sd_power_usbregstatus_get(&usb_reg); + }else +#endif + { + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + usb_reg = NRF_POWER->USBREGSTATUS; + } + + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + } + + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); + } +} diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h index 73f17d703..838e9fbea 100644 --- a/ports/nrf/tick.h +++ b/ports/nrf/tick.h @@ -26,7 +26,7 @@ #ifndef MICROPY_INCLUDED_NRF_TICK_H #define MICROPY_INCLUDED_NRF_TICK_H -#include "mpconfigport.h" +#include "py/mpconfig.h" #include diff --git a/ports/nrf/usb/tusb_config.h b/ports/nrf/usb/tusb_config.h deleted file mode 100644 index 626b99eeb..000000000 --- a/ports/nrf/usb/tusb_config.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************/ -/*! - @file tusb_config.h - @author hathach (tinyusb.org) - - @section LICENSE - - Software License Agreement (BSD License) - - Copyright (c) 2013, hathach (tinyusb.org) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. Neither the name of the copyright holders nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ -/**************************************************************************/ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -//--------------------------------------------------------------------+ -// COMMON CONFIGURATION -//--------------------------------------------------------------------+ -#define CFG_TUSB_MCU OPT_MCU_NRF5X -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - -#define CFG_TUSB_DEBUG 0 - -/*------------- RTOS -------------*/ -#define CFG_TUSB_OS OPT_OS_NONE -//#define CFG_TUD_TASK_QUEUE_SZ 16 -//#define CFG_TUD_TASK_PRIO 0 -//#define CFG_TUD_TASK_STACK_SZ 150 - -//--------------------------------------------------------------------+ -// DEVICE CONFIGURATION -//--------------------------------------------------------------------+ - -#define CFG_TUD_ENDOINT0_SIZE 64 - -/*------------- Descriptors -------------*/ -/* Enable auto generated descriptor, tinyusb will try its best to create - * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file - * - * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled - */ -#define CFG_TUD_DESC_AUTO 0 - -//------------- CLASS -------------// -#define CFG_TUD_CDC 1 -#define CFG_TUD_MSC 1 -#define CFG_TUD_HID 1 - -/*------------------------------------------------------------------*/ -/* CLASS DRIVER - *------------------------------------------------------------------*/ - -/*------------- CDC -------------*/ -// FIFO size of CDC TX and RX -#define CFG_TUD_CDC_RX_BUFSIZE 1024 -#define CFG_TUD_CDC_TX_BUFSIZE 1024 - -/* TX is sent automatically on every Start of Frame event ~ 1ms. - * If not enabled, application must call tud_cdc_flush() periodically - * Note: Enabled this could overflow device task, if it does, define - * CFG_TUD_TASK_QUEUE_SZ with large value - */ -#define CFG_TUD_CDC_FLUSH_ON_SOF 0 - - -/*------------- MSC -------------*/ -// Number of supported Logical Unit Number (At least 1) -#define CFG_TUD_MSC_MAXLUN 1 - -// Number of Blocks -#define CFG_TUD_MSC_BLOCK_NUM (256*1024)/512 - -// Block size -#define CFG_TUD_MSC_BLOCK_SZ 512 - -// Buffer size for each read/write transfer, the more the better -#define CFG_TUD_MSC_BUFSIZE (4*1024) - -// Vendor name included in Inquiry response, max 8 bytes -#define CFG_TUD_MSC_VENDOR "Adafruit" - -// Product name included in Inquiry response, max 16 bytes -#define CFG_TUD_MSC_PRODUCT "CircuitPY nRF52" - -// Product revision string included in Inquiry response, max 4 bytes -#define CFG_TUD_MSC_PRODUCT_REV "1.0" - - -//--------------------------------------------------------------------+ -// USB RAM PLACEMENT -//--------------------------------------------------------------------+ -#define CFG_TUSB_ATTR_USBRAM -#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4) - - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/ports/nrf/usb/usb.c b/ports/nrf/usb/usb.c deleted file mode 100644 index 248d31e21..000000000 --- a/ports/nrf/usb/usb.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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 "nrfx.h" -#include "nrfx_power.h" -#include "tick.h" -#include "usb.h" -#include "lib/utils/interrupt_char.h" -#include "lib/mp-readline/readline.h" - -#ifdef SOFTDEVICE_PRESENT -#include "nrf_sdm.h" -#include "nrf_soc.h" -#endif - -/* tinyusb function that handles power event (detected, ready, removed) - * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. - */ -extern void tusb_hal_nrf_power_event(uint32_t event); - -void usb_init(void) { - - // USB power may already be ready at this time -> no event generated - // We need to invoke the handler based on the status initially - uint32_t usb_reg; - -#ifdef SOFTDEVICE_PRESENT - uint8_t sd_en = false; - (void) sd_softdevice_is_enabled(&sd_en); - - if ( sd_en ) { - sd_power_usbdetected_enable(true); - sd_power_usbpwrrdy_enable(true); - sd_power_usbremoved_enable(true); - - sd_power_usbregstatus_get(&usb_reg); - }else -#endif - { - // Power module init - const nrfx_power_config_t pwr_cfg = { 0 }; - nrfx_power_init(&pwr_cfg); - - // Register tusb function as USB power handler - const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; - nrfx_power_usbevt_init(&config); - - nrfx_power_usbevt_enable(); - - usb_reg = NRF_POWER->USBREGSTATUS; - } - - if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) { - tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); - } - - if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) { - tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); - } - - // create serial number based on device unique id - extern uint16_t usb_desc_str_serial[1 + 16]; - - char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 8; j++) { - uint8_t nibble = (NRF_FICR->DEVICEID[i] >> j * 4) & 0xf; - - // Invert order since it is LE, +1 for skipping descriptor header - uint8_t const idx = (15 - (i * 8 + j)) + 1; - usb_desc_str_serial[idx] = nibble_to_hex[nibble]; - } - } - - tusb_init(); - -#if MICROPY_KBD_EXCEPTION - // Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() callback will be invoked when Ctrl+C is received - // This callback always got invoked regardless of mp_interrupt_char value since we only set it once here - tud_cdc_set_wanted_char(CHAR_CTRL_C); -#endif -} - -//--------------------------------------------------------------------+ -// tinyusb callbacks -//--------------------------------------------------------------------+ - -// Invoked when device is mounted -void tud_mount_cb(void) { -} - -// Invoked when device is unmounted -void tud_umount_cb(void) { -} - -uint32_t tusb_hal_millis(void) { - uint64_t ms; - uint32_t us; - current_tick(&ms, &us); - return (uint32_t) ms; -} - - -// Invoked when cdc when line state changed e.g connected/disconnected -// Use to reset to DFU when disconnect with 1200 bps -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - (void) itf; // interface ID, not used - - // DTR = false is counted as disconnected - if ( !dtr ) - { - cdc_line_coding_t coding; - tud_cdc_get_line_coding(&coding); - - if ( coding.bit_rate == 1200 ) - { - enum { DFU_MAGIC_SERIAL = 0x4e }; - - NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL; - NVIC_SystemReset(); - } - } -} - -#if MICROPY_KBD_EXCEPTION - -/** - * Callback invoked when received an "wanted" char. - * @param itf Interface index (for multiple cdc interfaces) - * @param wanted_char The wanted char (set previously) - */ -void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) -{ - (void) itf; // not used - - // Workaround for using lib/utils/interrupt_char.c - // Compare mp_interrupt_char with wanted_char and ignore if not matched - if (mp_interrupt_char == wanted_char) { - tud_cdc_read_flush(); // flush read fifo - mp_keyboard_interrupt(); - } -} - -#endif - diff --git a/ports/nrf/usb/usb.h b/ports/nrf/usb/usb.h deleted file mode 100644 index 203260874..000000000 --- a/ports/nrf/usb/usb.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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. - */ - -#ifndef MICROPY_INCLUDED_NRF_USB_H -#define MICROPY_INCLUDED_NRF_USB_H - -#include "tusb.h" - -void usb_init(void); - -#endif // MICROPY_INCLUDED_NRF_USB_H diff --git a/ports/nrf/usb/usb_desc.c b/ports/nrf/usb/usb_desc.c deleted file mode 100644 index 10d603528..000000000 --- a/ports/nrf/usb/usb_desc.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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 "usb_desc.h" -#include "common-hal/usb_hid/Device.h" - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -#define USB_VID 0x239A - -/* Note: different class combination e.g CDC and (CDC + MSC) should have different - * PID since Host OS will "remembered" device driver after the first plug */ -#define USB_PID 0x802A - -/*------------- Interface Numbering -------------*/ -enum { - ITF_NUM_CDC = 0 , - ITF_NUM_CDC_DATA , - ITF_NUM_MSC , - ITF_NUM_HID_GEN , - ITF_NUM_TOTAL -}; - -enum { - ITF_STR_LANGUAGE = 0 , - ITF_STR_MANUFACTURER , - ITF_STR_PRODUCT , - ITF_STR_SERIAL , - ITF_STR_CDC , - ITF_STR_MSC , - ITF_STR_HID -}; - -/*------------- Endpoint Numbering & Size -------------*/ -#define _EP_IN(x) (0x80 | (x)) -#define _EP_OUT(x) (x) - -// CDC -#define EP_CDC_NOTIF _EP_IN ( ITF_NUM_CDC+1 ) -#define EP_CDC_NOTIF_SIZE 8 - -#define EP_CDC_OUT _EP_OUT( ITF_NUM_CDC+2 ) -#define EP_CDC_IN _EP_IN ( ITF_NUM_CDC+2 ) - -// Mass Storage -#define EP_MSC_OUT _EP_OUT( ITF_NUM_MSC+1 ) -#define EP_MSC_IN _EP_IN ( ITF_NUM_MSC+1 ) - -// HID composite = keyboard + mouse + gamepad + etc ... -#define EP_HID_GEN _EP_IN ( ITF_NUM_HID_GEN+1 ) -#define EP_HID_GEN_SIZE 16 - -//--------------------------------------------------------------------+ -// STRING DESCRIPTORS -//--------------------------------------------------------------------+ - -uint16_t usb_desc_str_serial[1+16] = { TUD_DESC_STR_HEADER(16) }; - -// array of pointer to string descriptors -uint16_t const * const string_desc_arr [] = -{ - // 0 index is supported language = English - TUD_DESC_STRCONV(0x0409), - - // 1 Manufacturer - TUD_DESC_STRCONV('A','d','a','f','r','u','i','t',' ','I','n','d','u','s','t','r','i','e','s'), - - // 2 Product - TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','n','R','F','5','2'), - - // 3 Serials TODO use chip ID - usb_desc_str_serial, - - // 4 CDC Interface - TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','S','e','r','i','a','l'), - - // 5 MSC Interface - TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','S','t','o','r','a','g','e'), - - // 6 HID Interface - TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','H','I','D'), - - // Custom Interface -// TUD_DESC_STRCONV('C','i','r','c','u','i','t','P','y',' ','C','u','s','t','o','m') -}; - - -//--------------------------------------------------------------------+ -// Device Descriptor -//--------------------------------------------------------------------+ -tusb_desc_device_t const usb_desc_dev = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - - #if CFG_TUD_CDC - // Use Interface Association Descriptor (IAD) for CDC - // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, - #else - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - #endif - - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, - - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 // TODO multiple configurations -}; - -//--------------------------------------------------------------------+ -// HID Report Descriptor -//--------------------------------------------------------------------+ -uint8_t const usb_desc_hid_generic_report[] = -{ -#if USB_HID_DEVICE_KEYBOARD - HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(USB_HID_REPORT_ID_KEYBOARD), ), -#endif - -#if USB_HID_DEVICE_MOUSE - HID_REPORT_DESC_MOUSE( HID_REPORT_ID(USB_HID_REPORT_ID_MOUSE), ), -#endif - -#if USB_HID_DEVICE_CONSUMER - HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(USB_HID_REPORT_ID_CONSUMER), ), -#endif - -#if USB_HID_DEVICE_SYS_CONTROL - HID_REPORT_DESC_SYSTEM_CONTROL( HID_REPORT_ID(USB_HID_REPORT_ID_SYS_CONTROL ), ), -#endif - -#if USB_HID_DEVICE_GAMEPAD - HID_REPORT_DESC_GAMEPAD( HID_REPORT_ID(USB_HID_REPORT_ID_GAMEPAD ), ) -#endif - -}; - -//--------------------------------------------------------------------+ -// Configuration Descriptor -//--------------------------------------------------------------------+ -usb_desc_cfg_t const usb_desc_cfg = -{ - .config = - { - .bLength = sizeof(tusb_desc_configuration_t), - .bDescriptorType = TUSB_DESC_CONFIGURATION, - .wTotalLength = sizeof(usb_desc_cfg_t), - .bNumInterfaces = ITF_NUM_TOTAL, - .bConfigurationValue = 1, - .iConfiguration = 0x00, - .bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER, - .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100) - }, - - // IAD points to CDC Interfaces - .cdc = - { - .iad = - { - .bLength = sizeof(tusb_desc_interface_assoc_t), - .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, - - .bFirstInterface = ITF_NUM_CDC, - .bInterfaceCount = 2, - - .bFunctionClass = TUSB_CLASS_CDC, - .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, - .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, - .iFunction = 0 - }, - - //------------- CDC Communication Interface -------------// - .comm_itf = - { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - .bInterfaceNumber = ITF_NUM_CDC, - .bAlternateSetting = 0, - .bNumEndpoints = 1, - .bInterfaceClass = TUSB_CLASS_CDC, - .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, - .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, - .iInterface = ITF_STR_CDC - }, - - .header = - { - .bLength = sizeof(cdc_desc_func_header_t), - .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC, - .bDescriptorSubType = CDC_FUNC_DESC_HEADER, - .bcdCDC = 0x0120 - }, - - .call = - { - .bLength = sizeof(cdc_desc_func_call_management_t), - .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC, - .bDescriptorSubType = CDC_FUNC_DESC_CALL_MANAGEMENT, - .bmCapabilities = { 0 }, - .bDataInterface = ITF_NUM_CDC+1, - }, - - .acm = - { - .bLength = sizeof(cdc_desc_func_acm_t), - .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC, - .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, - .bmCapabilities = { // 0x02 - .support_line_request = 1, - } - }, - - .union_func = - { - .bLength = sizeof(cdc_desc_func_union_t), // plus number of - .bDescriptorType = TUSB_DESC_CLASS_SPECIFIC, - .bDescriptorSubType = CDC_FUNC_DESC_UNION, - .bControlInterface = ITF_NUM_CDC, - .bSubordinateInterface = ITF_NUM_CDC+1, - }, - - .ep_notif = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_CDC_NOTIF, - .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, - .wMaxPacketSize = { .size = EP_CDC_NOTIF_SIZE }, - .bInterval = 0x10 - }, - - //------------- CDC Data Interface -------------// - .data_itf = - { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - .bInterfaceNumber = ITF_NUM_CDC+1, - .bAlternateSetting = 0x00, - .bNumEndpoints = 2, - .bInterfaceClass = TUSB_CLASS_CDC_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0x00 - }, - - .ep_out = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_CDC_OUT, - .bmAttributes = { .xfer = TUSB_XFER_BULK }, - .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE }, - .bInterval = 0 - }, - - .ep_in = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_CDC_IN, - .bmAttributes = { .xfer = TUSB_XFER_BULK }, - .wMaxPacketSize = { .size = CFG_TUD_CDC_EPSIZE }, - .bInterval = 0 - }, - }, - - //------------- Mass Storage-------------// - .msc = - { - .itf = - { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - .bInterfaceNumber = ITF_NUM_MSC, - .bAlternateSetting = 0x00, - .bNumEndpoints = 2, - .bInterfaceClass = TUSB_CLASS_MSC, - .bInterfaceSubClass = MSC_SUBCLASS_SCSI, - .bInterfaceProtocol = MSC_PROTOCOL_BOT, - .iInterface = ITF_STR_MSC - }, - - .ep_out = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_MSC_OUT, - .bmAttributes = { .xfer = TUSB_XFER_BULK }, - .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE}, - .bInterval = 1 - }, - - .ep_in = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_MSC_IN, - .bmAttributes = { .xfer = TUSB_XFER_BULK }, - .wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE}, - .bInterval = 1 - } - }, - - //------------- HID Generic Multiple report -------------// - .hid_generic = - { - .itf = - { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - .bInterfaceNumber = ITF_NUM_HID_GEN, - .bAlternateSetting = 0x00, - .bNumEndpoints = 1, - .bInterfaceClass = TUSB_CLASS_HID, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = ITF_STR_HID - }, - - .hid_desc = - { - .bLength = sizeof(tusb_hid_descriptor_hid_t), - .bDescriptorType = HID_DESC_TYPE_HID, - .bcdHID = 0x0111, - .bCountryCode = HID_Local_NotSupported, - .bNumDescriptors = 1, - .bReportType = HID_DESC_TYPE_REPORT, - .wReportLength = sizeof(usb_desc_hid_generic_report) - }, - - .ep_in = - { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = EP_HID_GEN, - .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, - .wMaxPacketSize = { .size = EP_HID_GEN_SIZE }, - .bInterval = 0x0A - } - } -}; - - -// tud_desc_set is required by tinyusb stack -tud_desc_set_t tud_desc_set = -{ - .device = &usb_desc_dev, - .config = &usb_desc_cfg, - .string_arr = (uint8_t const **) string_desc_arr, - .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), - - .hid_report = - { - .generic = usb_desc_hid_generic_report, - .boot_keyboard = NULL, - .boot_mouse = NULL - } -}; diff --git a/ports/nrf/usb/usb_desc.h b/ports/nrf/usb/usb_desc.h deleted file mode 100644 index 19f3f6d5b..000000000 --- a/ports/nrf/usb/usb_desc.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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. - */ - -#ifndef USB_DESC_H_ -#define USB_DESC_H_ - -#include "tusb.h" - -#ifdef __cplusplus - extern "C" { -#endif - -/*------------- Configuration Descriptor -------------*/ -typedef struct ATTR_PACKED -{ - tusb_desc_configuration_t config; - - //------------- CDC -------------// - struct ATTR_PACKED - { - tusb_desc_interface_assoc_t iad; - - //CDC Control Interface - tusb_desc_interface_t comm_itf; - cdc_desc_func_header_t header; - cdc_desc_func_call_management_t call; - cdc_desc_func_acm_t acm; - cdc_desc_func_union_t union_func; - tusb_desc_endpoint_t ep_notif; - - //CDC Data Interface - tusb_desc_interface_t data_itf; - tusb_desc_endpoint_t ep_out; - tusb_desc_endpoint_t ep_in; - }cdc; - - //------------- Mass Storage -------------// - struct ATTR_PACKED - { - tusb_desc_interface_t itf; - tusb_desc_endpoint_t ep_out; - tusb_desc_endpoint_t ep_in; - } msc; - - //------------- HID -------------// - struct ATTR_PACKED - { - tusb_desc_interface_t itf; - tusb_hid_descriptor_hid_t hid_desc; - tusb_desc_endpoint_t ep_in; - } hid_generic; - -} usb_desc_cfg_t; - - -// Descriptors set used by tinyusb stack -extern tud_desc_set_t tud_desc_set; - - -#ifdef __cplusplus - } -#endif - -#endif /* USB_DESC_H_ */ diff --git a/ports/nrf/usb/usb_msc_flash.c b/ports/nrf/usb/usb_msc_flash.c deleted file mode 100644 index f78c24145..000000000 --- a/ports/nrf/usb/usb_msc_flash.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 hathach for Adafruit Industries - * - * 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 "tusb.h" -#include "internal_flash.h" - -// For updating fatfs's cache -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "lib/oofatfs/ff.h" -#include "py/mpstate.h" - -#include "supervisor/shared/autoreload.h" - -/*------------------------------------------------------------------*/ -/* MACRO TYPEDEF CONSTANT ENUM - *------------------------------------------------------------------*/ -#define MSC_FLASH_ADDR_END 0xED000 -#define MSC_FLASH_SIZE (256*1024) -#define MSC_FLASH_ADDR_START (MSC_FLASH_ADDR_END-MSC_FLASH_SIZE) -#define MSC_FLASH_BLOCK_SIZE 512 - -#define FL_PAGE_SZ 4096 - -// Callback invoked when received an SCSI command not in built-in list below -// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE -// - READ10 and WRITE10 has their own callbacks -int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) { - const void* response = NULL; - uint16_t resplen = 0; - - switch ( scsi_cmd[0] ) { - case SCSI_CMD_TEST_UNIT_READY: - // Command that host uses to check our readiness before sending other commands - resplen = 0; - break; - - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - - case SCSI_CMD_START_STOP_UNIT: - // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power - /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd; - // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well - // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage - start_stop->start; - start_stop->load_eject; - */ - resplen = 0; - break; - - default: - // Set Sense = Invalid Command Operation - tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - - // negative means error -> tinyusb could stall and/or response with failed status - resplen = -1; - break; - } - - // return len must not larger than bufsize - if ( resplen > bufsize ) { - resplen = bufsize; - } - - // copy response to stack's buffer if any - if ( response && resplen ) { - memcpy(buffer, response, resplen); - } - - return resplen; -} - -// Callback invoked when received READ10 command. -// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. -int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { - (void) lun; - (void) offset; - - const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; - - internal_flash_read_blocks(buffer, lba, block_count); - - return block_count * MSC_FLASH_BLOCK_SIZE; -} - -// Callback invoked when received WRITE10 command. -// Process data in buffer to disk's storage and return number of written bytes -int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { - (void) lun; - (void) offset; - - const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; - - // bufsize <= CFG_TUD_MSC_BUFSIZE (4096) - internal_flash_write_blocks(buffer, lba, block_count); - - // update fatfs's cache if address matches - fs_user_mount_t* vfs = MP_STATE_VM(vfs_mount_table)->obj; - - if ( (lba <= vfs->fatfs.winsect) && (vfs->fatfs.winsect <= (lba + bufsize / MSC_FLASH_BLOCK_SIZE)) ) { - memcpy(vfs->fatfs.win, buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), MSC_FLASH_BLOCK_SIZE); - } - - return block_count * MSC_FLASH_BLOCK_SIZE; -} - -// Callback invoked when WRITE10 command is completed (status received and accepted by host). -// used to flush any pending cache. -void tud_msc_write10_complete_cb (uint8_t lun) { - (void) lun; - - // flush pending cache when write10 is complete - internal_flash_flush(); - - // This write is complete, start the autoreload clock. - autoreload_start(); -} diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 555f32c92..2d12b8b76 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -61,4 +61,7 @@ extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_o // Return actual SPI bus frequency. uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self); +// This is used by the supervisor to claim SPI devices indefinitely. +extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h index 2bc553c4a..cb9a64b5e 100644 --- a/shared-bindings/usb_hid/Device.h +++ b/shared-bindings/usb_hid/Device.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H -#include "common-hal/usb_hid/Device.h" +#include "shared-module/usb_hid/Device.h" const mp_obj_type_t usb_hid_device_type; diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index 9e4508355..6d3a28523 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#include "mpconfigport.h" - +#include "py/mpconfig.h" #include "py/obj.h" #include "py/runtime.h" diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index edce286b1..f09edd785 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -32,8 +32,12 @@ #include "py/mperrno.h" #include "py/obj.h" #include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/os/__init__.h" #include "shared-bindings/storage/__init__.h" +#include "supervisor/filesystem.h" +#include "supervisor/flash.h" +#include "supervisor/usb.h" STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { if (vfs == MP_VFS_NONE) { @@ -138,3 +142,25 @@ void common_hal_storage_umount_path(const char* mount_path) { mp_obj_t common_hal_storage_getmount(const char *mount_path) { return storage_object_from_path(mount_path); } + +void common_hal_storage_remount(const char *mount_path, bool readonly) { + if (strcmp(mount_path, "/") != 0) { + mp_raise_OSError(MP_EINVAL); + } + + #ifdef USB_AVAILABLE + // TODO(dhalbert): is this is a good enough check? It checks for + // CDC enabled. There is no "MSC enabled" check. + if (usb_enabled()) { + mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active.")); + } + #endif + + supervisor_flash_set_usb_writable(readonly); +} + +void common_hal_storage_erase_filesystem(void) { + filesystem_init(false, true); // Force a re-format. + common_hal_mcu_reset(); + // We won't actually get here, since we're resetting. +} diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c new file mode 100644 index 000000000..820e14ad0 --- /dev/null +++ b/shared-module/usb_hid/Device.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 +#include "tick.h" +#include "py/runtime.h" +#include "shared-bindings/usb_hid/Device.h" +#include "shared-module/usb_hid/Device.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { + return self->usage_page; +} + +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { + return self->usage; +} + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + if (len != self->report_length) { + mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length); + } + + // Wait until interface is ready, timeout = 2 seconds + uint64_t end_ticks = ticks_ms + 2000; + while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { } + + if ( !tud_hid_generic_ready() ) { + mp_raise_msg(&mp_type_OSError, translate("USB Busy")); + } + + memcpy(self->report_buffer, report, len); + + if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) { + mp_raise_msg(&mp_type_OSError, translate("USB Error")); + } +} + +// Callbacks invoked when receive Get_Report request through control endpoint +uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { + // only support Input Report + if ( report_type != HID_REPORT_TYPE_INPUT ) return 0; + + // index is ID-1 + uint8_t idx = ( report_id ? (report_id-1) : 0 ); + + // fill buffer with current report + memcpy(buffer, usb_hid_devices[idx].report_buffer, reqlen); + return reqlen; +} + +// Callbacks invoked when receive Set_Report request through control endpoint +void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { + // index is ID-1 + uint8_t idx = ( report_id ? (report_id-1) : 0 ); + + if ( report_type == HID_REPORT_TYPE_OUTPUT ) { + // Check if it is Keyboard device + if ( (usb_hid_devices[idx].usage_page == HID_USAGE_PAGE_DESKTOP) && (usb_hid_devices[idx].usage == HID_USAGE_DESKTOP_KEYBOARD) ) { + // This is LED indicator (CapsLock, NumLock) + // TODO Light up some LED here + } + } +} diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h new file mode 100644 index 000000000..10f2ee897 --- /dev/null +++ b/shared-module/usb_hid/Device.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_HID_DEVICE_H +#define SHARED_MODULE_USB_HID_DEVICE_H + +#include +#include + +#include "py/obj.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct { + mp_obj_base_t base; + uint8_t* report_buffer; + uint8_t report_id; + uint8_t report_length; + uint8_t usage_page; + uint8_t usage; +} usb_hid_device_obj_t; + + +extern usb_hid_device_obj_t usb_hid_devices[]; + +#ifdef __cplusplus + } +#endif + +#endif /* SHARED_MODULE_USB_HID_DEVICE_H */ diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c new file mode 100644 index 000000000..c0f9c897c --- /dev/null +++ b/shared-module/usb_hid/__init__.c @@ -0,0 +1,154 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "shared-module/usb_hid/Device.h" +#include "shared-bindings/usb_hid/Device.h" +#include "tusb.h" + +#ifdef USB_HID_REPORT_ID_KEYBOARD +static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD]; +#endif + +#ifdef USB_HID_REPORT_ID_MOUSE +static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE]; +#endif + +#ifdef USB_HID_REPORT_ID_CONSUMER +static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER]; +#endif + +#ifdef USB_HID_REPORT_ID_SYS_CONTROL +static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL]; +#endif + +#ifdef USB_HID_REPORT_ID_GAMEPAD +static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD]; +#endif + +#ifdef USB_HID_REPORT_ID_DIGITIZER +static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; +#endif + +usb_hid_device_obj_t usb_hid_devices[] = { +#if USB_HID_REPORT_ID_KEYBOARD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = keyboard_report_buffer , + .report_id = USB_HID_REPORT_ID_KEYBOARD , + .report_length = USB_HID_REPORT_LENGTH_KEYBOARD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_KEYBOARD , + }, +#endif + +#if USB_HID_REPORT_ID_MOUSE + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = mouse_report_buffer , + .report_id = USB_HID_REPORT_ID_MOUSE , + .report_length = USB_HID_REPORT_LENGTH_MOUSE , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_MOUSE , + }, +#endif + +#if USB_HID_REPORT_ID_CONSUMER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = consumer_report_buffer , + .report_id = USB_HID_REPORT_ID_CONSUMER , + .report_length = USB_HID_REPORT_LENGTH_CONSUMER , + .usage_page = HID_USAGE_PAGE_CONSUMER , + .usage = HID_USAGE_CONSUMER_CONTROL , + }, +#endif + +#if USB_HID_REPORT_ID_SYS_CONTROL + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = sys_control_report_buffer , + .report_id = USB_HID_REPORT_ID_SYS_CONTROL , + .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_SYSTEM_CONTROL , + }, +#endif + +#if USB_HID_REPORT_ID_GAMEPAD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = gamepad_report_buffer , + .report_id = USB_HID_REPORT_ID_GAMEPAD , + .report_length = USB_HID_REPORT_LENGTH_GAMEPAD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_GAMEPAD , + }, +#endif + +#if USB_HID_REPORT_ID_DIGITIZER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = digitizer_report_buffer , + .report_id = USB_HID_REPORT_ID_DIGITIZER , + .report_length = USB_HID_REPORT_LENGTH_DIGITIZER , + .usage_page = 0x0D , + .usage = 0x02 , + }, +#endif +}; + + +mp_obj_tuple_t common_hal_usb_hid_devices = { + .base = { + .type = &mp_type_tuple, + }, + .len = USB_HID_NUM_DEVICES, + .items = { +#if USB_HID_NUM_DEVICES >= 1 + (mp_obj_t) &usb_hid_devices[0], +#endif +#if USB_HID_NUM_DEVICES >= 2 + (mp_obj_t) &usb_hid_devices[1], +#endif +#if USB_HID_NUM_DEVICES >= 3 + (mp_obj_t) &usb_hid_devices[2], +#endif +#if USB_HID_NUM_DEVICES >= 4 + (mp_obj_t) &usb_hid_devices[3], +#endif +#if USB_HID_NUM_DEVICES >= 5 + (mp_obj_t) &usb_hid_devices[4], +#endif +#if USB_HID_NUM_DEVICES >= 6 + (mp_obj_t) &usb_hid_devices[5], +#endif + } +}; diff --git a/supervisor/flash.h b/supervisor/flash.h new file mode 100644 index 000000000..ae6a44fd0 --- /dev/null +++ b/supervisor/flash.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#ifdef EXTERNAL_FLASH_DEVICE_COUNT +#include "supervisor/shared/external_flash/external_flash.h" +#else +#include "supervisor/internal_flash.h" +#endif + +void supervisor_flash_set_usb_writable(bool usb_writable); +void supervisor_flash_init(void); +uint32_t supervisor_flash_get_block_size(void); +uint32_t supervisor_flash_get_block_count(void); +void supervisor_flash_flush(void); + +// these return 0 on success, non-zero on error +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); + +struct _fs_user_mount_t; +void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs); +void supervisor_flash_flush(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H diff --git a/supervisor/flash_root_pointers.h b/supervisor/flash_root_pointers.h new file mode 100644 index 000000000..634ae58d3 --- /dev/null +++ b/supervisor/flash_root_pointers.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H + +#ifdef EXTERNAL_FLASH_DEVICE_COUNT +#include "supervisor/shared/external_flash/external_flash_root_pointers.h" +#else +#include "supervisor/internal_flash_root_pointers.h" +#endif + +#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H diff --git a/supervisor/port.h b/supervisor/port.h index f30d87b47..dd4a82209 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -57,6 +57,9 @@ void reset_port(void); // Reset the rest of the board. void reset_board(void); +// Reset to the bootloader +void reset_to_bootloader(void); + #ifdef NRF52_SERIES void HardFault_Handler(void); #endif diff --git a/supervisor/serial.h b/supervisor/serial.h index 9446ee71c..84b3062a3 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -30,8 +30,18 @@ #include #include +#include "py/mpconfig.h" + +#ifdef CIRCUITPY_BOOT_OUTPUT_FILE +#include "lib/oofatfs/ff.h" + +FIL* boot_output_file; +#endif + void serial_init(void); void serial_write(const char* text); +// Only writes up to given length. Does not check for null termination at all. +void serial_write_substring(const char* text, uint32_t length); char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); diff --git a/supervisor/shared/external_flash/common_commands.h b/supervisor/shared/external_flash/common_commands.h new file mode 100644 index 000000000..cc0da2175 --- /dev/null +++ b/supervisor/shared/external_flash/common_commands.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H + +#define CMD_READ_JEDEC_ID 0x9f +#define CMD_READ_DATA 0x03 +#define CMD_FAST_READ_DATA 0x0B +#define CMD_SECTOR_ERASE 0x20 +// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID +#define CMD_DISABLE_WRITE 0x04 +#define CMD_ENABLE_WRITE 0x06 +#define CMD_PAGE_PROGRAM 0x02 +// #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID +#define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS2 0x35 +#define CMD_WRITE_STATUS_BYTE1 0x01 +#define CMD_WRITE_STATUS_BYTE2 0x31 +#define CMD_DUAL_READ 0x3b +#define CMD_QUAD_READ 0x6b +#define CMD_ENABLE_RESET 0x66 +#define CMD_RESET 0x99 + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h new file mode 100644 index 000000000..06fc178cb --- /dev/null +++ b/supervisor/shared/external_flash/devices.h @@ -0,0 +1,375 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H + +#include +#include + +typedef struct { + uint32_t total_size; + uint16_t start_up_time_us; + + // Three response bytes to 0x9f JEDEC ID command. + uint8_t manufacturer_id; + uint8_t memory_type; + uint8_t capacity; + + // Max clock speed for all operations and the fastest read mode. + uint8_t max_clock_speed_mhz; + + // Bitmask for Quad Enable bit if present. 0x00 otherwise. This is for the highest byte in the + // status register. + uint8_t quad_enable_bit_mask; + + bool has_sector_protection : 1; + + // Supports the 0x0b fast read command with 8 dummy cycles. + bool supports_fast_read : 1; + + // Supports the fast read, quad output command 0x6b with 8 dummy cycles. + bool supports_qspi : 1; + + // Supports the quad input page program command 0x32. This is known as 1-1-4 because it only + // uses all four lines for data. + bool supports_qspi_writes: 1; + + // Requires a separate command 0x31 to write to the second byte of the status register. + // Otherwise two byte are written via 0x01. + bool write_status_register_split: 1; + + // True when the status register is a single byte. This implies the Quad Enable bit is in the + // first byte and the Read Status Register 2 command (0x35) is unsupported. + bool single_status_byte: 1; +} external_flash_device; + +// Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. Its on the SAMD21 +// Xplained board. +// Datasheet: https://www.adestotech.com/wp-content/uploads/doc8715.pdf +#define AT25DF081A {\ + .total_size = (1 << 20), /* 1 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x1f, \ + .memory_type = 0x45, \ + .capacity = 0x01, \ + .max_clock_speed_mhz = 85, \ + .quad_enable_bit_mask = 0x00, \ + .has_sector_protection = true, \ + .supports_fast_read = true, \ + .supports_qspi = false, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Gigadevice GD25Q16C 2MiB SPI flash. +// Datasheet: http://www.gigadevice.com/wp-content/uploads/2017/12/DS-00086-GD25Q16C-Rev2.6.pdf +#define GD25Q16C {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc8, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Gigadevice GD25Q64C 8MiB SPI flash. +// Datasheet: http://www.elm-tech.com/en/products/spi-flash-memory/gd25q64/gd25q64.pdf +#define GD25Q64C {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc8, \ + .memory_type = 0x40, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = true, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL064L 8MiB SPI flash. +// Datasheet: http://www.cypress.com/file/316661/download +#define S25FL064L {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 300, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x60, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 108, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL116K 2MiB SPI flash. +// Datasheet: http://www.cypress.com/file/196886/download +#define S25FL116K {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 108, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL216K 2MiB SPI flash. +// Datasheet: http://www.cypress.com/file/197346/download +#define S25FL216K {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 65, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = false, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16FW 2MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q16fw%20revj%2005182017%20sfdp.pdf +#define W25Q16FW {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf +#define W25Q16JV_IQ {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) +// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf +#define W25Q16JV_IM {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +// Settings for the Winbond W25Q32BV 4MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf +#define W25Q32BV {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 104, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} +// Settings for the Winbond W25Q32JV-IM 4MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf +#define W25Q32JV_IM {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +// Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) +// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf +#define W25Q64JV_IM {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf +#define W25Q64JV_IQ {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q80DL 1MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf +#define W25Q80DL {\ + .total_size = (1 << 20), /* 1 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x14, \ + .max_clock_speed_mhz = 104, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + + +// Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_SQ {\ + .total_size = (1 << 24), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Macronix MX25R6435F 8MiB SPI flash. +// Datasheet: http://www.macronix.com/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf +// By default its in lower power mode which can only do 8mhz. In high power mode it can do 80mhz. +#define MX25R6435F {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc2, \ + .memory_type = 0x28, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 8, \ + .quad_enable_bit_mask = 0x40, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = true, \ +} + +// Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_PM {\ + .total_size = (1 << 24), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .has_quad_enable = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c new file mode 100644 index 000000000..defdfa393 --- /dev/null +++ b/supervisor/shared/external_flash/external_flash.c @@ -0,0 +1,615 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "external_flash.h" + +#include +#include + +#include "supervisor/spi_flash_api.h" +#include "supervisor/shared/external_flash/common_commands.h" +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/misc.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/memory.h" +#include "supervisor/shared/rgb_led_status.h" + +#define SPI_FLASH_PART1_START_BLOCK (0x1) + +#define NO_SECTOR_LOADED 0xFFFFFFFF + +// The currently cached sector in the cache, ram or flash based. +static uint32_t current_sector; + +const external_flash_device possible_devices[EXTERNAL_FLASH_DEVICE_COUNT] = {EXTERNAL_FLASH_DEVICES}; + +static const external_flash_device* flash_device = NULL; + +// Track which blocks (up to 32) in the current sector currently live in the +// cache. +static uint32_t dirty_mask; + +static supervisor_allocation* supervisor_cache = NULL; + +// Wait until both the write enable and write in progress bits have cleared. +static bool wait_for_flash_ready(void) { + uint8_t read_status_response[1] = {0x00}; + bool ok = true; + // Both the write enable and write in progress bits should be low. + do { + ok = spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); + } while (ok && (read_status_response[0] & 0x3) != 0); + return ok; +} + +// Turn on the write enable bit so we can program and erase the flash. +static bool write_enable(void) { + return spi_flash_command(CMD_ENABLE_WRITE); +} + +// Read data_length's worth of bytes starting at address into data. +static bool read_flash(uint32_t address, uint8_t* data, uint32_t data_length) { + if (flash_device == NULL) { + return false; + } + if (!wait_for_flash_ready()) { + return false; + } + return spi_flash_read_data(address, data, data_length); +} + +// Writes data_length's worth of bytes starting at address from data. Assumes +// that the sector that address resides in has already been erased. So make sure +// to run erase_sector. +static bool write_flash(uint32_t address, const uint8_t* data, uint32_t data_length) { + if (flash_device == NULL) { + return false; + } + // Don't bother writing if the data is all 1s. Thats equivalent to the flash + // state after an erase. + bool all_ones = true; + for (uint16_t i = 0; i < data_length; i++) { + if (data[i] != 0xff) { + all_ones = false; + break; + } + } + if (all_ones) { + return true; + } + + for (uint32_t bytes_written = 0; + bytes_written < data_length; + bytes_written += SPI_FLASH_PAGE_SIZE) { + if (!wait_for_flash_ready() || !write_enable()) { + return false; + } + + if (!spi_flash_write_data(address + bytes_written, (uint8_t*) data + bytes_written, + SPI_FLASH_PAGE_SIZE)) { + return false; + } + } + return true; +} + +static bool page_erased(uint32_t sector_address) { + // Check the first few bytes to catch the common case where there is data + // without using a bunch of memory. + uint8_t short_buffer[4]; + if (read_flash(sector_address, short_buffer, 4)) { + for (uint16_t i = 0; i < 4; i++) { + if (short_buffer[i] != 0xff) { + return false; + } + } + } else { + return false; + } + + // Now check the full length. + uint8_t full_buffer[FILESYSTEM_BLOCK_SIZE]; + if (read_flash(sector_address, full_buffer, FILESYSTEM_BLOCK_SIZE)) { + for (uint16_t i = 0; i < FILESYSTEM_BLOCK_SIZE; i++) { + if (short_buffer[i] != 0xff) { + return false; + } + } + } else { + return false; + } + return true; +} + +// Erases the given sector. Make sure you copied all of the data out of it you +// need! Also note, sector_address is really 24 bits. +static bool erase_sector(uint32_t sector_address) { + // Before we erase the sector we need to wait for any writes to finish and + // and then enable the write again. + if (!wait_for_flash_ready() || !write_enable()) { + return false; + } + + spi_flash_sector_command(CMD_SECTOR_ERASE, sector_address); + return true; +} + +// Sector is really 24 bits. +static bool copy_block(uint32_t src_address, uint32_t dest_address) { + // Copy page by page to minimize RAM buffer. + uint16_t page_size = SPI_FLASH_PAGE_SIZE; + uint8_t buffer[page_size]; + for (uint32_t i = 0; i < FILESYSTEM_BLOCK_SIZE / page_size; i++) { + if (!read_flash(src_address + i * page_size, buffer, page_size)) { + return false; + } + if (!write_flash(dest_address + i * page_size, buffer, page_size)) { + return false; + } + } + return true; +} + +void supervisor_flash_init(void) { + if (flash_device != NULL) { + return; + } + + // Delay to give the SPI Flash time to get going. + // TODO(tannewt): Only do this when we know power was applied vs a reset. + uint16_t max_start_up_delay_us = 0; + for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { + if (possible_devices[i].start_up_time_us > max_start_up_delay_us) { + max_start_up_delay_us = possible_devices[i].start_up_time_us; + } + } + common_hal_mcu_delay_us(max_start_up_delay_us); + + spi_flash_init(); + + // The response will be 0xff if the flash needs more time to start up. + uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff}; + while (jedec_id_response[0] == 0xff) { + spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); + } + + for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { + const external_flash_device* possible_device = &possible_devices[i]; + if (jedec_id_response[0] == possible_device->manufacturer_id && + jedec_id_response[1] == possible_device->memory_type && + jedec_id_response[2] == possible_device->capacity) { + flash_device = possible_device; + break; + } + } + + if (flash_device == NULL) { + return; + } + + // We don't know what state the flash is in so wait for any remaining writes and then reset. + uint8_t read_status_response[1] = {0x00}; + // The write in progress bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); + } while ((read_status_response[0] & 0x1) != 0); + // The suspended write/erase bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS2, read_status_response, 1); + } while ((read_status_response[0] & 0x80) != 0); + + + spi_flash_command(CMD_ENABLE_RESET); + spi_flash_command(CMD_RESET); + + // Wait 30us for the reset + common_hal_mcu_delay_us(30); + + spi_flash_init_device(flash_device); + + // Activity LED for flash writes. +#ifdef MICROPY_HW_LED_MSC + gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(MICROPY_HW_LED_MSC, GPIO_DIRECTION_OUT); + // There's already a pull-up on the board. + gpio_set_pin_level(MICROPY_HW_LED_MSC, false); +#endif + + if (flash_device->has_sector_protection) { + write_enable(); + + // Turn off sector protection + uint8_t data[1] = {0x00}; + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1); + } + + // Turn off writes in case this is a microcontroller only reset. + spi_flash_command(CMD_DISABLE_WRITE); + + wait_for_flash_ready(); + + current_sector = NO_SECTOR_LOADED; + dirty_mask = 0; + MP_STATE_VM(flash_ram_cache) = NULL; +} + +// The size of each individual block. +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +// The total number of available blocks. +uint32_t supervisor_flash_get_block_count(void) { + // We subtract one erase sector size because we may use it as a staging area + // for writes. + return SPI_FLASH_PART1_START_BLOCK + (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; +} + +// Flush the cache that was written to the scratch portion of flash. Only used +// when ram is tight. +static bool flush_scratch_flash(void) { + // First, copy out any blocks that we haven't touched from the sector we've + // cached. + bool copy_to_scratch_ok = true; + uint32_t scratch_sector = flash_device->total_size - SPI_FLASH_ERASE_SIZE; + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + if ((dirty_mask & (1 << i)) == 0) { + copy_to_scratch_ok = copy_to_scratch_ok && + copy_block(current_sector + i * FILESYSTEM_BLOCK_SIZE, + scratch_sector + i * FILESYSTEM_BLOCK_SIZE); + } + } + if (!copy_to_scratch_ok) { + // TODO(tannewt): Do more here. We opted to not erase and copy bad data + // in. We still risk losing the data written to the scratch sector. + return false; + } + // Second, erase the current sector. + erase_sector(current_sector); + // Finally, copy the new version into it. + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + copy_block(scratch_sector + i * FILESYSTEM_BLOCK_SIZE, + current_sector + i * FILESYSTEM_BLOCK_SIZE); + } + return true; +} + +// Attempts to allocate a new set of page buffers for caching a full sector in +// ram. Each page is allocated separately so that the GC doesn't need to provide +// one huge block. We can free it as we write if we want to also. +static bool allocate_ram_cache(void) { + uint8_t blocks_per_sector = SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + + uint32_t table_size = blocks_per_sector * pages_per_block * sizeof(uint32_t); + // Attempt to allocate outside the heap first. + supervisor_cache = allocate_memory(table_size + SPI_FLASH_ERASE_SIZE, false); + if (supervisor_cache != NULL) { + MP_STATE_VM(flash_ram_cache) = (uint8_t **) supervisor_cache->ptr; + uint8_t* page_start = (uint8_t *) supervisor_cache->ptr + table_size; + + for (uint8_t i = 0; i < blocks_per_sector; i++) { + for (uint8_t j = 0; j < pages_per_block; j++) { + uint32_t offset = i * pages_per_block + j; + MP_STATE_VM(flash_ram_cache)[offset] = page_start + offset * SPI_FLASH_PAGE_SIZE; + } + } + return true; + } + + MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t), false); + if (MP_STATE_VM(flash_ram_cache) == NULL) { + return false; + } + // Declare i and j outside the loops in case we fail to allocate everything + // we need. In that case we'll give it back. + uint8_t i = 0; + uint8_t j = 0; + bool success = true; + for (i = 0; i < blocks_per_sector; i++) { + for (j = 0; j < pages_per_block; j++) { + uint8_t *page_cache = m_malloc_maybe(SPI_FLASH_PAGE_SIZE, false); + if (page_cache == NULL) { + success = false; + break; + } + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j] = page_cache; + } + if (!success) { + break; + } + } + // We couldn't allocate enough so give back what we got. + if (!success) { + // We add 1 so that we delete 0 when i is 1. Going to zero (i >= 0) + // would never stop because i is unsigned. + i++; + for (; i > 0; i--) { + for (; j > 0; j--) { + m_free(MP_STATE_VM(flash_ram_cache)[(i - 1) * pages_per_block + (j - 1)]); + } + j = pages_per_block; + } + m_free(MP_STATE_VM(flash_ram_cache)); + MP_STATE_VM(flash_ram_cache) = NULL; + } + return success; +} + +// Flush the cached sector from ram onto the flash. We'll free the cache unless +// keep_cache is true. +static bool flush_ram_cache(bool keep_cache) { + // First, copy out any blocks that we haven't touched from the sector + // we've cached. If we don't do this we'll erase the data during the sector + // erase below. + bool copy_to_ram_ok = true; + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + if ((dirty_mask & (1 << i)) == 0) { + for (uint8_t j = 0; j < pages_per_block; j++) { + copy_to_ram_ok = read_flash( + current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], + SPI_FLASH_PAGE_SIZE); + if (!copy_to_ram_ok) { + break; + } + } + } + if (!copy_to_ram_ok) { + break; + } + } + + if (!copy_to_ram_ok) { + return false; + } + // Second, erase the current sector. + erase_sector(current_sector); + // Lastly, write all the data in ram that we've cached. + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + for (uint8_t j = 0; j < pages_per_block; j++) { + write_flash(current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], + SPI_FLASH_PAGE_SIZE); + if (!keep_cache && supervisor_cache == NULL) { + m_free(MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j]); + } + } + } + // We're done with the cache for now so give it back. + if (!keep_cache) { + if (supervisor_cache != NULL) { + free_memory(supervisor_cache); + supervisor_cache = NULL; + } else { + m_free(MP_STATE_VM(flash_ram_cache)); + } + MP_STATE_VM(flash_ram_cache) = NULL; + } + return true; +} + +// Delegates to the correct flash flush method depending on the existing cache. +static void spi_flash_flush_keep_cache(bool keep_cache) { + if (current_sector == NO_SECTOR_LOADED) { + return; + } + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + temp_status_color(ACTIVE_WRITE); + // If we've cached to the flash itself flush from there. + if (MP_STATE_VM(flash_ram_cache) == NULL) { + flush_scratch_flash(); + } else { + flush_ram_cache(keep_cache); + } + current_sector = NO_SECTOR_LOADED; + clear_temp_status(); + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif +} + +// External flash function used. If called externally we assume we won't need +// the cache after. +void supervisor_flash_flush(void) { + spi_flash_flush_keep_cache(false); +} + +// Builds a partition entry for the MBR. +static void build_partition(uint8_t *buf, int boot, int type, + uint32_t start_block, uint32_t num_blocks) { + buf[0] = boot; + + if (num_blocks == 0) { + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + } else { + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + } + + buf[4] = type; + + if (num_blocks == 0) { + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + } else { + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xff; + } + + buf[8] = start_block; + buf[9] = start_block >> 8; + buf[10] = start_block >> 16; + buf[11] = start_block >> 24; + + buf[12] = num_blocks; + buf[13] = num_blocks >> 8; + buf[14] = num_blocks >> 16; + buf[15] = num_blocks >> 24; +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (SPI_FLASH_PART1_START_BLOCK <= block && block < supervisor_flash_get_block_count()) { + // a block in partition 1 + block -= SPI_FLASH_PART1_START_BLOCK; + return block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +bool external_flash_read_block(uint8_t *dest, uint32_t block) { + if (block == 0) { + // Fake the MBR so we can decide on our own partition table + for (int i = 0; i < 446; i++) { + dest[i] = 0; + } + + build_partition(dest + 446, 0, 0x01 /* FAT12 */, + SPI_FLASH_PART1_START_BLOCK, + supervisor_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK); + build_partition(dest + 462, 0, 0, 0, 0); + build_partition(dest + 478, 0, 0, 0, 0); + build_partition(dest + 494, 0, 0, 0, 0); + + dest[510] = 0x55; + dest[511] = 0xaa; + + return true; + } else if (block < SPI_FLASH_PART1_START_BLOCK) { + memset(dest, 0, FILESYSTEM_BLOCK_SIZE); + return true; + } else { + // Non-MBR block, get data from flash memory. + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // We're reading from the currently cached sector. + if (current_sector == this_sector && (mask & dirty_mask) > 0) { + if (MP_STATE_VM(flash_ram_cache) != NULL) { + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (int i = 0; i < pages_per_block; i++) { + memcpy(dest + i * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], + SPI_FLASH_PAGE_SIZE); + } + return true; + } else { + uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; + return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE); + } + } + return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); + } +} + +bool external_flash_write_block(const uint8_t *data, uint32_t block) { + if (block < SPI_FLASH_PART1_START_BLOCK) { + // Fake writing below the flash partition. + return true; + } else { + // Non-MBR block, copy to cache + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + // Wait for any previous writes to finish. + wait_for_flash_ready(); + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // Flush the cache if we're moving onto a sector or we're writing the + // same block again. + if (current_sector != this_sector || (mask & dirty_mask) > 0) { + // Check to see if we'd write to an erased page. In that case we + // can write directly. + if (page_erased(address)) { + return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); + } + if (current_sector != NO_SECTOR_LOADED) { + spi_flash_flush_keep_cache(true); + } + if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) { + erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE); + wait_for_flash_ready(); + } + current_sector = this_sector; + dirty_mask = 0; + } + dirty_mask |= mask; + // Copy the block to the appropriate cache. + if (MP_STATE_VM(flash_ram_cache) != NULL) { + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (int i = 0; i < pages_per_block; i++) { + memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], + data + i * SPI_FLASH_PAGE_SIZE, + SPI_FLASH_PAGE_SIZE); + } + return true; + } else { + uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; + return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE); + } + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!external_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!external_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h new file mode 100644 index 000000000..852d183a7 --- /dev/null +++ b/supervisor/shared/external_flash/external_flash.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +// Erase sector size. +#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100) + +// These are common across all NOR Flash. +#define SPI_FLASH_ERASE_SIZE (1 << 12) +#define SPI_FLASH_PAGE_SIZE (256) + +#define SPI_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define SPI_FLASH_IDLE_TICK(tick) (((tick) & SPI_FLASH_SYSTICK_MASK) == 2) + +#ifndef SPI_FLASH_MAX_BAUDRATE +#define SPI_FLASH_MAX_BAUDRATE 8000000 +#endif + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H diff --git a/supervisor/shared/external_flash/external_flash_root_pointers.h b/supervisor/shared/external_flash/external_flash_root_pointers.h new file mode 100644 index 000000000..cb1b86d19 --- /dev/null +++ b/supervisor/shared/external_flash/external_flash_root_pointers.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H + +#include + +// We use this when we can allocate the whole cache in RAM. +#define FLASH_ROOT_POINTERS \ + uint8_t** flash_ram_cache; \ + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H diff --git a/supervisor/shared/external_flash/qspi_flash.c b/supervisor/shared/external_flash/qspi_flash.c new file mode 100644 index 000000000..48266540c --- /dev/null +++ b/supervisor/shared/external_flash/qspi_flash.c @@ -0,0 +1,56 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include "supervisor/shared/external_flash/common_commands.h" + +void check_quad_enable(const external_flash_device* device) { + if (device->quad_enable_bit_mask == 0x00) { + return; + } + + // Verify that QSPI mode is enabled. + uint8_t status; + if (device->single_status_byte) { + spi_flash_read_command(CMD_READ_STATUS, &status, 1); + } else { + spi_flash_read_command(CMD_READ_STATUS2, &status, 1); + } + + // Check the quad enable bit. + if ((status & device->quad_enable_bit_mask) == 0) { + uint8_t full_status[2] = {0x00, device->quad_enable_bit_mask}; + spi_flash_command(CMD_ENABLE_WRITE); + if (device->write_status_register_split) { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE2, full_status + 1, 1); + } else if (device->single_status_byte) { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status + 1, 1); + } else { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2); + } + } +} diff --git a/supervisor/shared/external_flash/qspi_flash.h b/supervisor/shared/external_flash/qspi_flash.h new file mode 100644 index 000000000..b72e37b26 --- /dev/null +++ b/supervisor/shared/external_flash/qspi_flash.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H + +void check_quad_enable(const external_flash_device* device); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H diff --git a/supervisor/shared/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c new file mode 100644 index 000000000..ec7101bc9 --- /dev/null +++ b/supervisor/shared/external_flash/spi_flash.c @@ -0,0 +1,150 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/external_flash.h" +#include "py/mpconfig.h" + +digitalio_digitalinout_obj_t cs_pin; +busio_spi_obj_t spi; + +const external_flash_device* flash_device; +uint32_t spi_flash_baudrate; + +// Enable the flash over SPI. +static void flash_enable(void) { + while (!common_hal_busio_spi_try_lock(&spi)) {} + common_hal_digitalio_digitalinout_set_value(&cs_pin, false); +} + +// Disable the flash over SPI. +static void flash_disable(void) { + common_hal_digitalio_digitalinout_set_value(&cs_pin, true); + common_hal_busio_spi_unlock(&spi); +} + +static bool transfer(uint8_t* command, uint32_t command_length, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { + flash_enable(); + bool status = common_hal_busio_spi_write(&spi, command, command_length); + if (status) { + if (data_in != NULL && data_out != NULL) { + status = common_hal_busio_spi_transfer(&spi, data_out, data_in, data_length); + } else if (data_out != NULL) { + status = common_hal_busio_spi_read(&spi, data_out, data_length, 0xff); + } else if (data_in != NULL) { + status = common_hal_busio_spi_write(&spi, data_in, data_length); + } + } + flash_disable(); + return status; +} + +static bool transfer_command(uint8_t command, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { + return transfer(&command, 1, data_in, data_out, data_length); +} + +bool spi_flash_command(uint8_t command) { + return transfer_command(command, NULL, NULL, 0); +} + +bool spi_flash_read_command(uint8_t command, uint8_t* data, uint32_t data_length) { + return transfer_command(command, NULL, data, data_length); +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t data_length) { + return transfer_command(command, data, NULL, data_length); +} + +// Pack the low 24 bits of the address into a uint8_t array. +static void address_to_bytes(uint32_t address, uint8_t* bytes) { + bytes[0] = (address >> 16) & 0xff; + bytes[1] = (address >> 8) & 0xff; + bytes[2] = address & 0xff; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + uint8_t request[4] = {command, 0x00, 0x00, 0x00}; + address_to_bytes(address, request + 1); + return transfer(request, 4, NULL, NULL, 0); +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length) { + uint8_t request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00}; + // Write the SPI flash write address into the bytes following the command byte. + address_to_bytes(address, request + 1); + flash_enable(); + common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8); + bool status = common_hal_busio_spi_write(&spi, request, 4); + if (status) { + status = common_hal_busio_spi_write(&spi, data, data_length); + } + flash_disable(); + return status; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) { + uint8_t request[5] = {CMD_READ_DATA, 0x00, 0x00, 0x00}; + uint8_t command_length = 4; + if (flash_device->supports_fast_read) { + request[0] = CMD_FAST_READ_DATA; + command_length = 5; + } + // Write the SPI flash write address into the bytes following the command byte. + address_to_bytes(address, request + 1); + flash_enable(); + common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8); + bool status = common_hal_busio_spi_write(&spi, request, command_length); + if (status) { + status = common_hal_busio_spi_read(&spi, data, data_length, 0xff); + } + flash_disable(); + return status; +} + +void spi_flash_init(void) { + common_hal_digitalio_digitalinout_construct(&cs_pin, SPI_FLASH_CS_PIN); + + // Set CS high (disabled). + common_hal_digitalio_digitalinout_switch_to_output(&cs_pin, true, DRIVE_MODE_PUSH_PULL); + + common_hal_busio_spi_construct(&spi, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN); + common_hal_busio_spi_never_reset(&spi); +} + +void spi_flash_init_device(const external_flash_device* device) { + flash_device = device; + spi_flash_baudrate = device->max_clock_speed_mhz * 1000000; + if (spi_flash_baudrate > SPI_FLASH_MAX_BAUDRATE) { + spi_flash_baudrate = SPI_FLASH_MAX_BAUDRATE; + } +} diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c new file mode 100644 index 000000000..264ba25f0 --- /dev/null +++ b/supervisor/shared/filesystem.c @@ -0,0 +1,109 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "extmod/vfs_fat.h" +#include "lib/oofatfs/ff.h" +#include "lib/oofatfs/diskio.h" + +#include "py/mpstate.h" + +#include "supervisor/flash.h" + +static mp_vfs_mount_t _mp_vfs; +static fs_user_mount_t _internal_vfs; + +static void make_empty_file(FATFS *fatfs, const char *path) { + FIL fp; + f_open(fatfs, &fp, path, FA_WRITE | FA_CREATE_ALWAYS); + f_close(&fp); +} + +// we don't make this function static because it needs a lot of stack and we +// want it to be executed without using stack within main() function +void filesystem_init(bool create_allowed, bool force_create) { + // init the vfs object + fs_user_mount_t *vfs_fat = &_internal_vfs; + vfs_fat->flags = 0; + supervisor_flash_init_vfs(vfs_fat); + + // try to mount the flash + FRESULT res = f_mount(&vfs_fat->fatfs); + + if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { + // No filesystem so create a fresh one, or reformat has been requested. + uint8_t working_buf[_MAX_SS]; + res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)); + // Flush the new file system to make sure it's repaired immediately. + supervisor_flash_flush(); + if (res != FR_OK) { + asm("bkpt"); + return; + } + + // set label + f_setlabel(&vfs_fat->fatfs, "CIRCUITPY"); + + // inhibit file indexing on MacOS + f_mkdir(&vfs_fat->fatfs, "/.fseventsd"); + make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index"); + make_empty_file(&vfs_fat->fatfs, "/.Trashes"); + make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log"); + + // and ensure everything is flushed + supervisor_flash_flush(); + } else if (res != FR_OK) { + asm("bkpt"); + return; + } + mp_vfs_mount_t *vfs = &_mp_vfs; + vfs->str = "/"; + vfs->len = 1; + vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); + vfs->next = NULL; + MP_STATE_VM(vfs_mount_table) = vfs; + + // The current directory is used as the boot up directory. + // It is set to the internal flash filesystem by default. + MP_STATE_PORT(vfs_cur) = vfs; +} + +void filesystem_flush(void) { + supervisor_flash_flush(); +} + +void filesystem_writable_by_python(bool writable) { + fs_user_mount_t *vfs = &_internal_vfs; + + if (writable) { + vfs->flags |= FSUSER_USB_WRITABLE; + } else { + vfs->flags &= ~FSUSER_USB_WRITABLE; + } +} + +bool filesystem_present(void) { + return true; +} diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c new file mode 100644 index 000000000..4fa2d8f75 --- /dev/null +++ b/supervisor/shared/flash.c @@ -0,0 +1,123 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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 "supervisor/flash.h" + +#include "extmod/vfs_fat.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#define VFS_INDEX 0 + +void supervisor_flash_set_usb_writable(bool usb_writable) { + mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); + for (uint8_t i = 0; current_mount != NULL; i++) { + if (i == VFS_INDEX) { + break; + } + current_mount = current_mount->next; + } + if (current_mount == NULL) { + return; + } + fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj; + + if (usb_writable) { + vfs->flags |= FSUSER_USB_WRITABLE; + } else { + vfs->flags &= ~FSUSER_USB_WRITABLE; + } +} + +// there is a singleton Flash object +const mp_obj_type_t supervisor_flash_type; +STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type}; + +STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 0, 0, false); + + // return singleton object + return (mp_obj_t)&supervisor_flash_obj; +} + +STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); + mp_uint_t ret = supervisor_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks); + +STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); + mp_uint_t ret = supervisor_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks); + +STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { + mp_int_t cmd = mp_obj_get_int(cmd_in); + switch (cmd) { + case BP_IOCTL_INIT: supervisor_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); + case BP_IOCTL_DEINIT: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly + case BP_IOCTL_SYNC: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); + case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_count()); + case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_size()); + default: return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_ioctl_obj, supervisor_flash_obj_ioctl); + +STATIC const mp_rom_map_elem_t supervisor_flash_obj_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&supervisor_flash_obj_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&supervisor_flash_obj_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&supervisor_flash_obj_ioctl_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_flash_obj_locals_dict, supervisor_flash_obj_locals_dict_table); + +const mp_obj_type_t supervisor_flash_type = { + { &mp_type_type }, + .name = MP_QSTR_Flash, + .make_new = supervisor_flash_obj_make_new, + .locals_dict = (mp_obj_t)&supervisor_flash_obj_locals_dict, +}; + +void supervisor_flash_init_vfs(fs_user_mount_t *vfs) { + vfs->base.type = &mp_fat_vfs_type; + vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; + vfs->fatfs.drv = vfs; + vfs->fatfs.part = 1; // flash filesystem lives on first partition + vfs->readblocks[0] = (mp_obj_t)&supervisor_flash_obj_readblocks_obj; + vfs->readblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->readblocks[2] = (mp_obj_t)supervisor_flash_read_blocks; // native version + vfs->writeblocks[0] = (mp_obj_t)&supervisor_flash_obj_writeblocks_obj; + vfs->writeblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->writeblocks[2] = (mp_obj_t)supervisor_flash_write_blocks; // native version + vfs->u.ioctl[0] = (mp_obj_t)&supervisor_flash_obj_ioctl_obj; + vfs->u.ioctl[1] = (mp_obj_t)&supervisor_flash_obj; +} diff --git a/supervisor/shared/micropython.c b/supervisor/shared/micropython.c new file mode 100644 index 000000000..245db11d4 --- /dev/null +++ b/supervisor/shared/micropython.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "supervisor/serial.h" +#include "lib/oofatfs/ff.h" +#include "py/mpconfig.h" + +#include "supervisor/shared/status_leds.h" + +int mp_hal_stdin_rx_chr(void) { + for (;;) { + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + if (serial_bytes_available()) { + toggle_rx_led(); + return serial_read(); + } + } +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + toggle_tx_led(); + + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + if (boot_output_file != NULL) { + UINT bytes_written = 0; + f_write(boot_output_file, str, len, &bytes_written); + } + #endif + + serial_write_substring(str, len); +} diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h index 24e071aac..9542b3197 100644 --- a/supervisor/shared/rgb_led_status.h +++ b/supervisor/shared/rgb_led_status.h @@ -33,7 +33,7 @@ #include "lib/utils/pyexec.h" #include "supervisor/port.h" -#include "mpconfigport.h" +#include "py/mpconfig.h" #include "rgb_led_colors.h" // Overall, the time module must be implemented. diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c new file mode 100644 index 000000000..058c4a7a4 --- /dev/null +++ b/supervisor/shared/serial.c @@ -0,0 +1,56 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "supervisor/serial.h" +#include "supervisor/usb.h" + +#include "tusb.h" + +void serial_init(void) { + usb_init(); +} + +bool serial_connected(void) { + return tud_cdc_connected(); +} + +char serial_read(void) { + return (char) tud_cdc_read_char(); +} + +bool serial_bytes_available(void) { + return tud_cdc_available() > 0; +} + +void serial_write(const char* text) { + tud_cdc_write(text, strlen(text)); +} + +void serial_write_substring(const char* text, uint32_t length) { + tud_cdc_write(text, length); +} diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c new file mode 100644 index 000000000..d99853ceb --- /dev/null +++ b/supervisor/shared/status_leds.c @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/status_leds.h" + +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#ifdef MICROPY_HW_LED_RX +digitalio_digitalinout_obj_t rx_led; +#endif + +#ifdef MICROPY_HW_LED_TX +digitalio_digitalinout_obj_t tx_led; +#endif + +void init_status_leds(void) { + #ifdef MICROPY_HW_LED_RX + common_hal_digitalio_digitalinout_construct(&rx_led, MICROPY_HW_LED_RX); + common_hal_digitalio_digitalinout_switch_to_output(&rx_led, true, DRIVE_MODE_PUSH_PULL); + #endif + #ifdef MICROPY_HW_LED_TX + common_hal_digitalio_digitalinout_construct(&tx_led, MICROPY_HW_LED_TX); + common_hal_digitalio_digitalinout_switch_to_output(&tx_led, true, DRIVE_MODE_PUSH_PULL); + #endif +} + +void toggle_rx_led(void) { + #ifdef MICROPY_HW_LED_RX + common_hal_digitalio_digitalinout_set_value(&rx_led, !common_hal_digitalio_digitalinout_get_value(&rx_led)); + #endif +} + + +void toggle_tx_led(void) { + #ifdef MICROPY_HW_LED_TX + common_hal_digitalio_digitalinout_set_value(&tx_led, !common_hal_digitalio_digitalinout_get_value(&tx_led)); + #endif +} diff --git a/supervisor/shared/status_leds.h b/supervisor/shared/status_leds.h new file mode 100644 index 000000000..30132753f --- /dev/null +++ b/supervisor/shared/status_leds.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H +#define MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H + +void init_status_leds(void); + +void toggle_rx_led(void); + +void toggle_tx_led(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h new file mode 100644 index 000000000..4693bfced --- /dev/null +++ b/supervisor/shared/usb/tusb_config.h @@ -0,0 +1,115 @@ +/**************************************************************************/ +/*! + @file tusb_config.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/**************************************************************************/ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#include "genhdr/autogen_usb_descriptor.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// COMMON CONFIGURATION +//--------------------------------------------------------------------+ +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + +#define CFG_TUSB_DEBUG 0 + +/*------------- RTOS -------------*/ +#define CFG_TUSB_OS OPT_OS_NONE +//#define CFG_TUD_TASK_QUEUE_SZ 16 +//#define CFG_TUD_TASK_PRIO 0 +//#define CFG_TUD_TASK_STACK_SZ 150 + +//--------------------------------------------------------------------+ +// DEVICE CONFIGURATION +//--------------------------------------------------------------------+ + +#define CFG_TUD_ENDOINT0_SIZE 64 + +/*------------- Descriptors -------------*/ +/* Enable auto generated descriptor, tinyusb will try its best to create + * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file + * + * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled + */ +#define CFG_TUD_DESC_AUTO 0 + +//------------- CLASS -------------// +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 1 +#define CFG_TUD_HID 1 + +/*------------------------------------------------------------------*/ +/* CLASS DRIVER + *------------------------------------------------------------------*/ + +/* TX is sent automatically on every Start of Frame event ~ 1ms. + * If not enabled, application must call tud_cdc_flush() periodically + * Note: Enabled this could overflow device task, if it does, define + * CFG_TUD_TASK_QUEUE_SZ with large value + */ +#define CFG_TUD_CDC_FLUSH_ON_SOF 0 + + +/*------------- MSC -------------*/ +// Number of supported Logical Unit Number (At least 1) +#define CFG_TUD_MSC_MAXLUN 1 + +// Number of Blocks +#define CFG_TUD_MSC_BLOCK_NUM (256*1024)/512 + + + +// Product revision string included in Inquiry response, max 4 bytes +#define CFG_TUD_MSC_PRODUCT_REV "1.0" + + +//--------------------------------------------------------------------+ +// USB RAM PLACEMENT +//--------------------------------------------------------------------+ +#define CFG_TUSB_ATTR_USBRAM +#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4) + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c new file mode 100644 index 000000000..1aa34e9e6 --- /dev/null +++ b/supervisor/shared/usb/usb.c @@ -0,0 +1,140 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "tick.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/port.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" + +#include "tusb.h" + +// Serial number as hex characters. This writes directly to the USB +// descriptor. +extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2]; + +void load_serial_number(void) { + // create serial number based on device unique id + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + + const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { + for (int j = 0; j < 2; j++) { + uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf; + // Strings are UTF-16-LE encoded. + usb_serial_number[1 + i * 2 + j] = nibble_to_hex[nibble]; + } + } +} + +bool _usb_enabled = false; + +bool usb_enabled(void) { + return _usb_enabled; +} + +void usb_init(void) { + init_usb_hardware(); + load_serial_number(); + + tusb_init(); + _usb_enabled = true; + +#if MICROPY_KBD_EXCEPTION + // Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() callback will be invoked when Ctrl+C is received + // This callback always got invoked regardless of mp_interrupt_char value since we only set it once here + tud_cdc_set_wanted_char(CHAR_CTRL_C); +#endif +} + +void usb_background(void) { + if (usb_enabled()) { + tusb_task(); + tud_cdc_write_flush(); + } +} + +//--------------------------------------------------------------------+ +// tinyusb callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) { +} + +// Invoked when device is unmounted +void tud_umount_cb(void) { +} + +uint32_t tusb_hal_millis(void) { + uint64_t ms; + uint32_t us; + current_tick(&ms, &us); + return (uint32_t) ms; +} + + +// Invoked when cdc when line state changed e.g connected/disconnected +// Use to reset to DFU when disconnect with 1200 bps +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { + (void) itf; // interface ID, not used + + // DTR = false is counted as disconnected + if ( !dtr ) + { + cdc_line_coding_t coding; + tud_cdc_get_line_coding(&coding); + + if ( coding.bit_rate == 1200 ) + { + reset_to_bootloader(); + } + } +} + +#if MICROPY_KBD_EXCEPTION + +/** + * Callback invoked when received an "wanted" char. + * @param itf Interface index (for multiple cdc interfaces) + * @param wanted_char The wanted char (set previously) + */ +void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) +{ + (void) itf; // not used + + // Workaround for using lib/utils/interrupt_char.c + // Compare mp_interrupt_char with wanted_char and ignore if not matched + if (mp_interrupt_char == wanted_char) { + tud_cdc_read_flush(); // flush read fifo + mp_keyboard_interrupt(); + } +} + +#endif diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c new file mode 100644 index 000000000..5a0de1ffc --- /dev/null +++ b/supervisor/shared/usb/usb_desc.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "supervisor/shared/usb/usb_desc.h" +#include "shared-module/usb_hid/Device.h" + +#include "genhdr/autogen_usb_descriptor.h" + +// tud_desc_set is required by tinyusb stack +tud_desc_set_t tud_desc_set = +{ + .device = &usb_desc_dev, + .config = &usb_desc_cfg, + .string_arr = (uint8_t const **) string_desc_arr, + .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), + + .hid_report = + { + .generic = hid_report_descriptor, + .boot_keyboard = NULL, + .boot_mouse = NULL + } +}; diff --git a/supervisor/shared/usb/usb_desc.h b/supervisor/shared/usb/usb_desc.h new file mode 100644 index 000000000..250147aa6 --- /dev/null +++ b/supervisor/shared/usb/usb_desc.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef USB_DESC_H_ +#define USB_DESC_H_ + +#include "lib/tinyusb/src/tusb.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// Descriptors set used by tinyusb stack +extern tud_desc_set_t tud_desc_set; + +#ifdef __cplusplus + } +#endif + +#endif /* USB_DESC_H_ */ diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c new file mode 100644 index 000000000..72dc40204 --- /dev/null +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -0,0 +1,205 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "tusb.h" +// // #include "supervisor/flash.h" + +// For updating fatfs's cache +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/diskio.h" +#include "lib/oofatfs/ff.h" +#include "py/mpstate.h" + +#include "supervisor/shared/autoreload.h" + +#define MSC_FLASH_BLOCK_SIZE 512 + +// The root FS is always at the end of the list. +static fs_user_mount_t* get_vfs(int lun) { + // TODO(tannewt): Return the mount which matches the lun where 0 is the end + // and is counted in reverse. + if (lun > 0) { + return NULL; + } + mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); + if (current_mount == NULL) { + return NULL; + } + while (current_mount->next != NULL) { + current_mount = current_mount->next; + } + return current_mount->obj; +} + +// Callback invoked when received an SCSI command not in built-in list below +// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE +// - READ10 and WRITE10 have their own callbacks +int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) { + const void* response = NULL; + uint16_t resplen = 0; + + switch ( scsi_cmd[0] ) { + case SCSI_CMD_TEST_UNIT_READY: + // Command that host uses to check our readiness before sending other commands + resplen = 0; + if (lun > 1) { + resplen = -1; + } else { + fs_user_mount_t* current_mount = get_vfs(lun); + if (current_mount == NULL) { + resplen = -1; + } + } + break; + + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + case SCSI_CMD_START_STOP_UNIT: + { + // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power + const scsi_start_stop_unit_t* start_stop = (const scsi_start_stop_unit_t*) scsi_cmd; + // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well + // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage + resplen = 0; + if (start_stop->load_eject == 1) { + if (lun > 1) { + resplen = -1; + } else { + fs_user_mount_t* current_mount = get_vfs(lun); + if (current_mount == NULL) { + resplen = -1; + } + } + } + } + break; + + default: + // Set Sense = Invalid Command Operation + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // negative means error -> tinyusb could stall and/or response with failed status + resplen = -1; + break; + } + + // return len must not larger than bufsize + if ( resplen > bufsize ) { + resplen = bufsize; + } + + // copy response to stack's buffer if any + if ( response && resplen ) { + memcpy(buffer, response, resplen); + } + + return resplen; +} + +bool tud_lun_capacity_cb(uint8_t lun, uint32_t* last_valid_sector, uint16_t* sector_size) { + fs_user_mount_t * vfs = get_vfs(lun); + if (vfs == NULL || + disk_ioctl(vfs, GET_SECTOR_COUNT, last_valid_sector) != RES_OK || + disk_ioctl(vfs, GET_SECTOR_SIZE, sector_size) != RES_OK) { + return false; + } + // Subtract one from the sector count to get the last valid sector. + (*last_valid_sector)--; + + return true; +} + +bool tud_msc_is_writable_cb(uint8_t lun) { + if (lun > 1) { + return false; + } + + fs_user_mount_t* vfs = get_vfs(lun); + if (vfs == NULL) { + return false; + } + if (vfs->writeblocks[0] == MP_OBJ_NULL || + (vfs->flags & FSUSER_USB_WRITABLE) == 0) { + return false; + } + return true; +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. +int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { + (void) lun; + (void) offset; + + const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; + + fs_user_mount_t * vfs = get_vfs(lun); + disk_read(vfs, buffer, lba, block_count); + + return block_count * MSC_FLASH_BLOCK_SIZE; +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes +int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { + (void) lun; + (void) offset; + + const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; + + fs_user_mount_t * vfs = get_vfs(lun); + disk_write(vfs, buffer, lba, block_count); + // Since by getting here we assume the mount is read-only to + // MicroPython let's update the cached FatFs sector if it's the one + // we just wrote. + #if _MAX_SS != _MIN_SS + if (vfs->ssize == MSC_FLASH_BLOCK_SIZE) { + #else + // The compiler can optimize this away. + if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) { + #endif + if (lba == vfs->fatfs.winsect && lba > 0) { + memcpy(vfs->fatfs.win, + buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), + MSC_FLASH_BLOCK_SIZE); + } + } + + return block_count * MSC_FLASH_BLOCK_SIZE; +} + +// Callback invoked when WRITE10 command is completed (status received and accepted by host). +// used to flush any pending cache. +void tud_msc_write10_complete_cb (uint8_t lun) { + (void) lun; + + // This write is complete, start the autoreload clock. + autoreload_start(); +} diff --git a/supervisor/spi_flash_api.h b/supervisor/spi_flash_api.h new file mode 100644 index 000000000..28cccb1b1 --- /dev/null +++ b/supervisor/spi_flash_api.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H + +#include +#include + +#include "supervisor/shared/external_flash/devices.h" + +// This API is implemented for both normal SPI peripherals and QSPI peripherals. + +bool spi_flash_command(uint8_t command); +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length); +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length); +bool spi_flash_sector_command(uint8_t command, uint32_t address); +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length); +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length); +void spi_flash_init(void); +void spi_flash_init_device(const external_flash_device* device); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index e516dcb2d..d870f799f 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -2,22 +2,78 @@ SRC_SUPERVISOR = \ main.c \ supervisor/port.c \ supervisor/shared/autoreload.c \ + supervisor/shared/filesystem.c \ + supervisor/shared/flash.c \ + supervisor/shared/micropython.c \ supervisor/shared/rgb_led_status.c \ supervisor/shared/stack.c \ + supervisor/shared/status_leds.c \ supervisor/shared/translate.c -ifeq ($(wildcard atmel-samd/supervisor/filesystem.c),) - SRC_SUPERVISOR += supervisor/filesystem.c +ifndef $(NO_USB) +NO_USB = $(wildcard supervisor/usb.c) +endif + + +# Choose which flash filesystem impl to use. +# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive. +# But that might not be true in the future.) +ifdef EXTERNAL_FLASH_DEVICES + CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \ + -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT) + + SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c + ifeq ($(SPI_FLASH_FILESYSTEM),1) + CFLAGS += -DSPI_FLASH_FILESYSTEM + SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c + endif + ifeq ($(QSPI_FLASH_FILESYSTEM),1) + CFLAGS += -DQSPI_FLASH_FILESYSTEM + SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c + endif else - SRC_SUPERVISOR += supervisor/stub/filesystem.c + SRC_SUPERVISOR += supervisor/internal_flash.c endif -ifeq ($(wildcard atmel-samd/supervisor/serial.c),) - SRC_SUPERVISOR += supervisor/serial.c +ifeq ($(USB),FALSE) + ifeq ($(wildcard supervisor/serial.c),) + SRC_SUPERVISOR += supervisor/stub/serial.c + else + SRC_SUPERVISOR += supervisor/serial.c + endif else - SRC_SUPERVISOR += supervisor/stub/serial.c + SRC_SUPERVISOR += lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/control.c \ + lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/class/msc/msc_device.c \ + lib/tinyusb/src/class/cdc/cdc_device.c \ + lib/tinyusb/src/class/hid/hid_device.c \ + lib/tinyusb/src/tusb.c \ + supervisor/shared/serial.c \ + supervisor/usb.c \ + supervisor/shared/usb/usb_desc.c \ + supervisor/shared/usb/usb.c \ + supervisor/shared/usb/usb_msc_flash.c \ + shared-bindings/usb_hid/__init__.c \ + shared-bindings/usb_hid/Device.c \ + shared-module/usb_hid/__init__.c \ + shared-module/usb_hid/Device.c \ + $(BUILD)/autogen_usb_descriptor.c + CFLAGS += -DUSB_AVAILABLE endif SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) $(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h + +$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" + $(Q)install -d $(BUILD)/genhdr + $(PYTHON3) ../../tools/gen_usb_descriptor.py \ + --manufacturer $(USB_MANUFACTURER)\ + --product $(USB_PRODUCT)\ + --vid $(USB_VID)\ + --pid $(USB_PID)\ + --serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\ + --output_c_file $(BUILD)/autogen_usb_descriptor.c\ + --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h diff --git a/supervisor/usb.h b/supervisor/usb.h new file mode 100644 index 000000000..c87540d40 --- /dev/null +++ b/supervisor/usb.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_USB_H +#define MICROPY_INCLUDED_SUPERVISOR_USB_H + +#include + +// Ports must call this as frequently as they can in order to keep the USB connection +// alive and responsive. +void usb_background(void); + +// Only inits the USB peripheral clocks and pins. The peripheral will be initialized by +// TinyUSB. +void init_usb_hardware(void); + +// Shared implementation. +bool usb_enabled(void); +void usb_init(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_USB_H diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py new file mode 100644 index 000000000..b50c0798f --- /dev/null +++ b/tools/gen_usb_descriptor.py @@ -0,0 +1,474 @@ +import argparse + +import os +import sys + +sys.path.append("../../tools/usb_descriptor") + +from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util +import hid_report_descriptors + +parser = argparse.ArgumentParser(description='Generate USB descriptors.') +parser.add_argument('--manufacturer', type=str, + help='manufacturer of the device') +parser.add_argument('--product', type=str, + help='product name of the device') +parser.add_argument('--vid', type=lambda x: int(x, 16), + help='vendor id') +parser.add_argument('--pid', type=lambda x: int(x, 16), + help='product id') +parser.add_argument('--serial_number_length', type=int, default=32, + help='length needed for the serial number in digits') +parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) +parser.add_argument('--output_h_file', type=argparse.FileType('w'), required=True) + +args = parser.parse_args() + +class StringIndex: + """Assign a monotonically increasing index to each unique string. Start with 0.""" + string_to_index = {} + index_to_variable = {} + strings = [] + + @classmethod + def index(cls, string, *, variable_name = None): + if string in cls.string_to_index: + idx = cls.string_to_index[string] + if not cls.index_to_variable[idx]: + cls.index_to_variable[idx] = variable_name + return idx + else: + idx = len(cls.strings) + cls.string_to_index[string] = idx + cls.strings.append(string) + cls.index_to_variable[idx] = variable_name + return idx + + @classmethod + def strings_in_order(cls): + return cls.strings + + + +# langid must be the 0th string descriptor +LANGID_INDEX = StringIndex.index("\u0409", variable_name="language_id") +assert LANGID_INDEX == 0 +SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length, variable_name="usb_serial_number") + +device = standard.DeviceDescriptor( + description="top", + idVendor=args.vid, + idProduct=args.pid, + iManufacturer=StringIndex.index(args.manufacturer), + iProduct=StringIndex.index(args.product), + iSerialNumber=SERIAL_NUMBER_INDEX) + +# Interface numbers are interface-set local and endpoints are interface local +# until util.join_interfaces renumbers them. + +cdc_union = cdc.Union( + description="CDC comm", + bMasterInterface=0x00, # Adjust this after interfaces are renumbered. + bSlaveInterface_list=[0x01]) # Adjust this after interfaces are renumbered. + +cdc_call_management = cdc.CallManagement( + description="CDC comm", + bmCapabilities=0x01, + bDataInterface=0x01) # Adjust this after interfaces are renumbered. + +cdc_comm_interface = standard.InterfaceDescriptor( + description="CDC comm", + bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, + iInterface=StringIndex.index("CircuitPython CDC control"), + subdescriptors=[ + cdc.Header( + description="CDC comm", + bcdCDC=0x0110), + cdc_call_management, + cdc.AbstractControlManagement( + description="CDC comm", + bmCapabilities=0x02), + cdc_union, + standard.EndpointDescriptor( + description="CDC comm in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + wMaxPacketSize=0x0040, + bInterval=0x10) + ]) + +cdc_data_interface = standard.InterfaceDescriptor( + description="CDC data", + bInterfaceClass=cdc.CDC_CLASS_DATA, + iInterface=StringIndex.index("CircuitPython CDC data"), + subdescriptors=[ + standard.EndpointDescriptor( + description="CDC data out", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + standard.EndpointDescriptor( + description="CDC data in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + ]) + +cdc_interfaces = [cdc_comm_interface, cdc_data_interface] + +msc_interfaces = [ + standard.InterfaceDescriptor( + description="MSC", + bInterfaceClass=msc.MSC_CLASS, + bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, + bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, + iInterface=StringIndex.index("CircuitPython Mass Storage"), + subdescriptors=[ + standard.EndpointDescriptor( + description="MSC in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0), + standard.EndpointDescriptor( + description="MSC out", + bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0) + ] + ) +] + +# Include only these HID devices. +# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now. +hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD") + +combined_hid_report_descriptor = hid.ReportDescriptor( + description="MULTIDEVICE", + report_descriptor=b''.join( + hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices )) + +hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices } +hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices } +hid_max_report_length = max(hid_report_lengths_dict.values()) + +# ASF4 expects keyboard and generic devices to have both in and out endpoints, +# and will fail (possibly silently) if both are not supplied. +hid_endpoint_in_descriptor = standard.EndpointDescriptor( + description="HID in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + bInterval=10) + +hid_interfaces = [ + standard.InterfaceDescriptor( + description="HID Multiple Devices", + bInterfaceClass=hid.HID_CLASS, + bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT, + bInterfaceProtocol=hid.HID_PROTOCOL_NONE, + iInterface=StringIndex.index("CircuitPython HID"), + subdescriptors=[ + hid.HIDDescriptor( + description="HID", + wDescriptorLength=len(bytes(combined_hid_report_descriptor))), + hid_endpoint_in_descriptor, + ] + ), + ] + +# Audio! +midi_in_jack = midi.InJackDescriptor( + description="MIDI PC <- CircuitPython internals", + bJackType=midi.JACK_TYPE_EMBEDDED, + iJack=0) +midi_out_jack = midi.OutJackDescriptor( + description="MIDI PC -> CircuitPython internals", + bJackType=midi.JACK_TYPE_EMBEDDED, + iJack=0) +audio_midi_interface = standard.InterfaceDescriptor( + description="All the audio", + bInterfaceClass=audio.AUDIO_CLASS_DEVICE, + bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, + bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, + iInterface=StringIndex.index("CircuitPython MIDI"), + subdescriptors=[ + midi.Header( + jacks_and_elements=[ + midi_in_jack, + midi.InJackDescriptor( + description="MIDI data in from user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), + midi_out_jack, + midi.OutJackDescriptor( + description="MIDI data out to user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0), + ] + ), + standard.EndpointDescriptor( + description="MIDI data out", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack]), + standard.EndpointDescriptor( + description="MIDI data in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack]), + ]) + +cs_ac_interface = audio10.AudioControlInterface( + description="Empty audio control", + audio_streaming_interfaces = [], + midi_streaming_interfaces = [ + audio_midi_interface + ] + ) + +audio_control_interface = standard.InterfaceDescriptor( + description="All the audio", + bInterfaceClass=audio.AUDIO_CLASS_DEVICE, + bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL, + bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, + iInterface=StringIndex.index("CircuitPython Audio"), + subdescriptors=[ + cs_ac_interface, + ]) + +# Audio streaming interfaces must occur before MIDI ones. +# audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces + +# This will renumber the endpoints to make them unique across descriptors, +# and renumber the interfaces in order. But we still need to fix up certain +# interface cross-references. +interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces) + +# Now adjust the CDC interface cross-references. + +cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber +cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber] + +cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber + +cdc_iad = standard.InterfaceAssociationDescriptor( + description="CDC IAD", + bFirstInterface=cdc_comm_interface.bInterfaceNumber, + bInterfaceCount=len(cdc_interfaces), + bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bFunctionProtocol=cdc.CDC_PROTOCOL_V25TER) # TODO(tannewt): can this be NONE (aka 0)? + +# audio_iad = standard.InterfaceAssociationDescriptor( +# description="Audio IAD", +# bFirstInterface=audio_control_interface.bInterfaceNumber, +# bInterfaceCount=len(audio_interfaces), +# bFunctionClass=audio.AUDIO_CLASS_DEVICE, +# bFunctionSubClass=audio.AUDIO_SUBCLASS_UNKNOWN, +# bFunctionProtocol=audio.AUDIO_PROTOCOL_V1) + + +descriptor_list = [] +descriptor_list.append(cdc_iad) +# descriptor_list.append(audio_iad) +descriptor_list.extend(cdc_interfaces) +descriptor_list.extend(msc_interfaces) +# descriptor_list.append(audio_control_interface) +# Put the CDC IAD just before the CDC interfaces. +# There appears to be a bug in the Windows composite USB driver that requests the +# HID report descriptor with the wrong interface number if the HID interface is not given +# first. However, it still fetches the descriptor anyway. We could reorder the interfaces but +# the Windows 7 Adafruit_usbser.inf file thinks CDC is at Interface 0, so we'll leave it +# there for backwards compatibility. +descriptor_list.extend(hid_interfaces) + +configuration = standard.ConfigurationDescriptor( + description="Composite configuration", + wTotalLength=(standard.ConfigurationDescriptor.bLength + + sum([len(bytes(x)) for x in descriptor_list])), + bNumInterfaces=len(interfaces)) +descriptor_list.insert(0, configuration) + +string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()] +serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX] + +c_file = args.output_c_file +h_file = args.output_h_file + + +c_file.write("""\ +#include + +#include "{H_FILE_NAME}" + +""".format(H_FILE_NAME=h_file.name)) + +c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=device.description, + CLASS=device.__class__)) + +c_file.write("""\ +const uint8_t usb_desc_dev[] = { +""") +for b in bytes(device): + c_file.write("0x{:02x}, ".format(b)) + +c_file.write("""\ +}; +""") + +c_file.write("""\ +const uint8_t usb_desc_cfg[] = { +""") + +# Write out all the regular descriptors as one long array (that's how ASF4 does it). +descriptor_length = 0 +for descriptor in descriptor_list: + c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=descriptor.description, + CLASS=descriptor.__class__)) + + b = bytes(descriptor) + notes = descriptor.notes() + i = 0 + + # This prints each subdescriptor on a separate line. + n = 0 + while i < len(b): + length = b[i] + for j in range(length): + c_file.write("0x{:02x}, ".format(b[i + j])) + c_file.write("// " + notes[n]) + n += 1 + c_file.write("\n") + i += length + descriptor_length += len(b) + +c_file.write("""\ +}; +""") + +pointers_to_strings = [] + +for idx, descriptor in enumerate(string_descriptors): + c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=descriptor.description, + CLASS=descriptor.__class__)) + + b = bytes(descriptor) + notes = descriptor.notes() + i = 0 + + # This prints each subdescriptor on a separate line. + variable_name = StringIndex.index_to_variable[idx] + if not variable_name: + variable_name = "string_descriptor{}".format(idx) + + const = "const " + if variable_name == "usb_serial_number": + const = "" + c_file.write("""\ +{const}uint16_t {NAME}[] = {{ +""".format(const=const, NAME=variable_name)) + pointers_to_strings.append("{name}".format(name=variable_name)) + n = 0 + while i < len(b): + length = b[i] + for j in range(length // 2): + c_file.write("0x{:04x}, ".format(b[i + 2*j + 1] << 8 | b[i + 2*j])) + n += 1 + c_file.write("\n") + i += length + c_file.write("""\ +}; +""") + +c_file.write("""\ +// array of pointer to string descriptors +uint16_t const * const string_desc_arr [] = +{ +""") +c_file.write(""",\ + +""".join(pointers_to_strings)) + +c_file.write(""" +}; +""") + +c_file.write("\n"); + +hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) + +# Now we values we need for the .h file. +h_file.write("""\ +#ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H +#define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H + +#include + +const uint8_t usb_desc_dev[{device_length}]; +// Make sure the control buffer is big enough to fit the descriptor. +#define CFG_TUD_ENUM_BUFFER_SIZE {max_configuration_length} +const uint8_t usb_desc_cfg[{configuration_length}]; +uint16_t usb_serial_number[{serial_number_length}]; +uint16_t const * const string_desc_arr [{string_descriptor_length}]; + +const uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}]; + +// Vendor name included in Inquiry response, max 8 bytes +#define CFG_TUD_MSC_VENDOR "{msc_vendor}" + +// Product name included in Inquiry response, max 16 bytes +#define CFG_TUD_MSC_PRODUCT "{msc_product}" + +""" +.format(serial_number_length=len(bytes(serial_number_descriptor)) // 2, + device_length=len(bytes(device)), + configuration_length=descriptor_length, + max_configuration_length=max(hid_descriptor_length, descriptor_length), + string_descriptor_length=len(pointers_to_strings), + HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)), + msc_vendor=args.manufacturer[:8], + msc_product=args.product[:16])) + +# #define the report ID's used in the combined HID descriptor +for name, id in hid_report_ids_dict.items(): + h_file.write("""\ +#define USB_HID_REPORT_ID_{name} {id} +""".format(name=name, + id=id)) + +h_file.write("\n") + +# #define the report sizes used in the combined HID descriptor +for name, length in hid_report_lengths_dict.items(): + h_file.write("""\ +#define USB_HID_REPORT_LENGTH_{name} {length} +""".format(name=name, + length=length)) + +h_file.write("\n") + +h_file.write("""\ +#define USB_HID_NUM_DEVICES {num_devices} +#define USB_HID_MAX_REPORT_LENGTH {max_length} +""".format(num_devices=len(hid_report_lengths_dict), + max_length=hid_max_report_length)) + + + +# Write out the report descriptor and info +c_file.write("""\ +const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{ +""".format(HID_DESCRIPTOR_LENGTH=hid_descriptor_length)) + +for b in bytes(combined_hid_report_descriptor): + c_file.write("0x{:02x}, ".format(b)) +c_file.write(""" +}; +""") + +h_file.write("""\ +#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H +""") diff --git a/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py new file mode 100644 index 000000000..f3b28ebcf --- /dev/null +++ b/tools/hid_report_descriptors.py @@ -0,0 +1,239 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Dan Halbert for Adafruit Industries +# +# 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. + +import struct + +""" +HID specific descriptors +======================== + +* Author(s): Dan Halbert +""" + +from adafruit_usb_descriptor import hid + +REPORT_IDS = { + "KEYBOARD" : 1, + "MOUSE" : 2, + "CONSUMER" : 3, + "SYS_CONTROL" : 4, + "GAMEPAD" : 5, + "DIGITIZER" : 6, + } + +# Byte count for each kind of report. Length does not include report ID in first byte. +REPORT_LENGTHS = { + "KEYBOARD" : 8, + "MOUSE" : 4, + "CONSUMER" : 2, + "SYS_CONTROL" : 1, + "GAMEPAD" : 6, + "DIGITIZER" : 5, + } + +KEYBOARD_WITH_ID = hid.ReportDescriptor( + description="KEYBOARD", + report_descriptor=bytes([ + # Regular keyboard + 0x05, 0x01, # Usage Page (Generic Desktop) + 0x09, 0x06, # Usage (Keyboard) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["KEYBOARD"], # Report ID (1) + 0x05, 0x07, # Usage Page (Keyboard) + 0x19, 224, # Usage Minimum (224) + 0x29, 231, # Usage Maximum (231) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x08, # Report Count (8) + 0x81, 0x02, # Input (Data, Variable, Absolute) + 0x81, 0x01, # Input (Constant) + 0x19, 0x00, # Usage Minimum (0) + 0x29, 101, # Usage Maximum (101) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 101, # Logical Maximum (101) + 0x75, 0x08, # Report Size (8) + 0x95, 0x06, # Report Count (6) + 0x81, 0x00, # Input (Data, Array) + 0x05, 0x08, # Usage Page (LED) + 0x19, 0x01, # Usage Minimum (1) + 0x29, 0x05, # Usage Maximum (5) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x05, # Report Count (5) + 0x91, 0x02, # Output (Data, Variable, Absolute) + 0x95, 0x03, # Report Count (3) + 0x91, 0x01, # Output (Constant) + 0xC0, # End Collection + ])) + +MOUSE_WITH_ID = hid.ReportDescriptor( + description="MOUSE", + report_descriptor=bytes([ + # Regular mouse + 0x05, 0x01, # Usage Page (Generic Desktop) + 0x09, 0x02, # Usage (Mouse) + 0xA1, 0x01, # Collection (Application) + 0x09, 0x01, # Usage (Pointer) + 0xA1, 0x00, # Collection (Physical) + 0x85, REPORT_IDS["MOUSE"], # Report ID (n) + 0x05, 0x09, # Usage Page (Button) + 0x19, 0x01, # Usage Minimum (0x01) + 0x29, 0x05, # Usage Maximum (0x05) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x95, 0x05, # Report Count (5) + 0x75, 0x01, # Report Size (1) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x01, # Report Count (1) + 0x75, 0x03, # Report Size (3) + 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x75, 0x08, # Report Size (8) + 0x95, 0x02, # Report Count (2) + 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0x09, 0x38, # Usage (Wheel) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x75, 0x08, # Report Size (8) + 0x95, 0x01, # Report Count (1) + 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + 0xC0, # End Collection + ])) + +CONSUMER_WITH_ID = hid.ReportDescriptor( + description="CONSUMER", + report_descriptor=bytes([ + # Consumer ("multimedia") keys + 0x05, 0x0C, # Usage Page (Consumer) + 0x09, 0x01, # Usage (Consumer Control) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["CONSUMER"], # Report ID (n) + 0x75, 0x10, # Report Size (16) + 0x95, 0x01, # Report Count (1) + 0x15, 0x01, # Logical Minimum (1) + 0x26, 0x8C, 0x02, # Logical Maximum (652) + 0x19, 0x01, # Usage Minimum (Consumer Control) + 0x2A, 0x8C, 0x02, # Usage Maximum (AC Send) + 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +SYS_CONTROL_WITH_ID = hid.ReportDescriptor( + description="SYS_CONTROL", + report_descriptor=bytes([ + # Power controls + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x80, # Usage (Sys Control) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["SYS_CONTROL"], # Report ID (n) + 0x75, 0x02, # Report Size (2) + 0x95, 0x01, # Report Count (1) + 0x15, 0x01, # Logical Minimum (1) + 0x25, 0x03, # Logical Maximum (3) + 0x09, 0x82, # Usage (Sys Sleep) + 0x09, 0x81, # Usage (Sys Power Down) + 0x09, 0x83, # Usage (Sys Wake Up) + 0x81, 0x60, # Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) + 0x75, 0x06, # Report Size (6) + 0x81, 0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +GAMEPAD_WITH_ID = hid.ReportDescriptor( + description="GAMEPAD", + report_descriptor=bytes([ + # Gamepad with 16 buttons and two joysticks + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x05, # Usage (Game Pad) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["GAMEPAD"], # Report ID (n) + 0x05, 0x09, # Usage Page (Button) + 0x19, 0x01, # Usage Minimum (Button 1) + 0x29, 0x10, # Usage Maximum (Button 16) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x10, # Report Count (16) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x09, 0x32, # Usage (Z) + 0x09, 0x35, # Usage (Rz) + 0x75, 0x08, # Report Size (8) + 0x95, 0x04, # Report Count (4) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +DIGITIZER_WITH_ID = hid.ReportDescriptor( + description="DIGITIZER", + report_descriptor=bytes([ + # Digitizer (used as an absolute pointer) + 0x05, 0x0D, # Usage Page (Digitizers) + 0x09, 0x02, # Usage (Pen) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["DIGITIZER"], # Report ID (n) + 0x09, 0x01, # Usage (Stylus) + 0xA1, 0x00, # Collection (Physical) + 0x09, 0x32, # Usage (In-Range) + 0x09, 0x42, # Usage (Tip Switch) + 0x09, 0x44, # Usage (Barrel Switch) + 0x09, 0x45, # Usage (Eraser Switch) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x04, # Report Count (4) + 0x81, 0x02, # Input (Data,Var,Abs) + 0x75, 0x04, # Report Size (4) -- Filler + 0x95, 0x01, # Report Count (1) -- Filler + 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x15, 0x00, # Logical Minimum (0) + 0x26, 0xff, 0x7f, # Logical Maximum (32767) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x75, 0x10, # Report Size (16) + 0x95, 0x02, # Report Count (2) + 0x81, 0x02, # Input (Data,Var,Abs) + 0xC0, # End Collection + 0xC0, # End Collection + ])) + +# Byte count for each kind of report. Length does not include report ID in first byte. +REPORT_DESCRIPTORS = { + "KEYBOARD" : KEYBOARD_WITH_ID, + "MOUSE" : MOUSE_WITH_ID, + "CONSUMER" : CONSUMER_WITH_ID, + "SYS_CONTROL" : SYS_CONTROL_WITH_ID, + "GAMEPAD" : GAMEPAD_WITH_ID, + "DIGITIZER" : DIGITIZER_WITH_ID, + } diff --git a/tools/usb_descriptor b/tools/usb_descriptor index 250784703..57bf602da 160000 --- a/tools/usb_descriptor +++ b/tools/usb_descriptor @@ -1 +1 @@ -Subproject commit 2507847031a0395465956539253cbfa27f87511e +Subproject commit 57bf602dac9cba8c4226f764c286cbc60103d67d -- cgit v1.2.3 From 168e23e466737fd25d6c7a524231781e35d1d49a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:11:43 -0800 Subject: Build refinement to handle warnings and quiet output --- lib/tinyusb | 2 +- py/py.mk | 4 ++-- shared-module/usb_hid/__init__.c | 12 ++++++------ supervisor/shared/usb/tusb_config.h | 1 + supervisor/supervisor.mk | 8 ++++++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 30e3c6413..537a29273 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 30e3c64134789416e10ed867fa12c210b808e98f +Subproject commit 537a29273c08b1e047004e1bd71c37af82937dd4 diff --git a/py/py.mk b/py/py.mk index 9874dde4d..c640e6cff 100644 --- a/py/py.mk +++ b/py/py.mk @@ -307,7 +307,7 @@ $(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEF # qstr data $(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h $(STEPECHO) "GEN $@" - $(PYTHON3) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ # Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get # created before we run the script to generate the .h @@ -315,7 +315,7 @@ $(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrd # the lines in "" and then unwrap after the preprocessor is finished. $(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h $(STEPECHO) "GEN $@" - $(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ $(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index c0f9c897c..f14fdd41e 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -58,7 +58,7 @@ static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; #endif usb_hid_device_obj_t usb_hid_devices[] = { -#if USB_HID_REPORT_ID_KEYBOARD +#ifdef USB_HID_REPORT_ID_KEYBOARD { .base = { .type = &usb_hid_device_type } , .report_buffer = keyboard_report_buffer , @@ -69,7 +69,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_MOUSE +#ifdef USB_HID_REPORT_ID_MOUSE { .base = { .type = &usb_hid_device_type } , .report_buffer = mouse_report_buffer , @@ -80,7 +80,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_CONSUMER +#ifdef USB_HID_REPORT_ID_CONSUMER { .base = { .type = &usb_hid_device_type } , .report_buffer = consumer_report_buffer , @@ -91,7 +91,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_SYS_CONTROL +#ifdef USB_HID_REPORT_ID_SYS_CONTROL { .base = { .type = &usb_hid_device_type } , .report_buffer = sys_control_report_buffer , @@ -102,7 +102,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_GAMEPAD +#ifdef USB_HID_REPORT_ID_GAMEPAD { .base = { .type = &usb_hid_device_type } , .report_buffer = gamepad_report_buffer , @@ -113,7 +113,7 @@ usb_hid_device_obj_t usb_hid_devices[] = { }, #endif -#if USB_HID_REPORT_ID_DIGITIZER +#ifdef USB_HID_REPORT_ID_DIGITIZER { .base = { .type = &usb_hid_device_type } , .report_buffer = digitizer_report_buffer , diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 4693bfced..649c390ac 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -75,6 +75,7 @@ #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 1 +#define CFG_TUD_CUSTOM_CLASS 0 /*------------------------------------------------------------------*/ /* CLASS DRIVER diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index d870f799f..ac982d277 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -66,10 +66,14 @@ SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) $(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h -$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) +$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate + +.INTERMEDIATE: autogen_usb_descriptor.intermediate + +autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) $(STEPECHO) "GEN $@" $(Q)install -d $(BUILD)/genhdr - $(PYTHON3) ../../tools/gen_usb_descriptor.py \ + $(Q)$(PYTHON3) ../../tools/gen_usb_descriptor.py \ --manufacturer $(USB_MANUFACTURER)\ --product $(USB_PRODUCT)\ --vid $(USB_VID)\ -- cgit v1.2.3 From be6b49c7128c9a09117aaa417b895767ebea924a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:27:18 -0800 Subject: Add back internal flash header and slim it down. --- ports/atmel-samd/supervisor/internal_flash.c | 2 ++ ports/atmel-samd/supervisor/internal_flash.h | 19 ------------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c index bf12ad0cd..6e097b214 100644 --- a/ports/atmel-samd/supervisor/internal_flash.c +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "supervisor/internal_flash.h" + #include #include diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h index 88c105386..b1074d93f 100644 --- a/ports/atmel-samd/supervisor/internal_flash.h +++ b/ports/atmel-samd/supervisor/internal_flash.h @@ -32,8 +32,6 @@ #include "sam.h" -#define FLASH_ROOT_POINTERS - #ifdef SAMD51 #define TOTAL_INTERNAL_FLASH_SIZE (FLASH_SIZE / 2) #endif @@ -49,21 +47,4 @@ #define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms #define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) -void internal_flash_init(void); -uint32_t internal_flash_get_block_size(void); -uint32_t internal_flash_get_block_count(void); -void internal_flash_irq_handler(void); -void internal_flash_flush(void); -bool internal_flash_read_block(uint8_t *dest, uint32_t block); -bool internal_flash_write_block(const uint8_t *src, uint32_t block); - -// these return 0 on success, non-zero on error -mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); - -extern const struct _mp_obj_type_t internal_flash_type; - -struct _fs_user_mount_t; -void flash_init_vfs(struct _fs_user_mount_t *vfs); - #endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H -- cgit v1.2.3 From 688f0e388bbb0ae4420c8e3145e83cb15d9b3829 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 00:49:02 -0800 Subject: Update MKR1300 board definition too --- ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h index ad9dc43b4..1e8d926fd 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h @@ -1,12 +1,10 @@ #define MICROPY_HW_BOARD_NAME "Arduino MKR1300" #define MICROPY_HW_MCU_NAME "samd21g18" -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#include "internal_flash.h" - #define CIRCUITPY_INTERNAL_NVM_SIZE 0 #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) -- cgit v1.2.3 From 28383afa11863f1fe289cc811c8eab403ea79f6f Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Fri, 9 Nov 2018 18:25:55 +0100 Subject: shared-module/os: Fix os.mkdir('a/b') This fixes commit a99f9427420d("'/' and '\' are also acceptable ends of the path now") which broke mkdir. The problem is where the directory name is a single letter like this: >>> os.mkdir('a') >>> os.mkdir('a/b') Traceback (most recent call last): File "", line 1, in OSError: [Errno 17] File exists >>> os.mkdir('a/bb') >>> I wasn't smart enough to fix this in the oofatfs library, so I did it in the os shared module by creating a path lookup function for the os methods that only deals with directories. I reverted the library change introduced by the aforementioned commit. This means that os.stat and os.rename can't handle trailing slashes. This is to avoid allowing filenames with trailing slashes to pass through. In order to handle trailing slashes for these it would be necessary to check if it really is a directory before stripping. I didn't do this since the original issue was to make os.chdir tolerate trailing slashes. There's an open MicroPython issue #2929 wrt. trailing slashes and mkdir. --- lib/oofatfs/ff.c | 2 +- shared-module/os/__init__.c | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/oofatfs/ff.c b/lib/oofatfs/ff.c index 4e8680545..b0984756b 100644 --- a/lib/oofatfs/ff.c +++ b/lib/oofatfs/ff.c @@ -2579,8 +2579,8 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ lfn[di++] = w; /* Store the Unicode character */ } - cf = ((w < ' ') || ((w == '/' || w == '\\') && p[si+1] < ' ')) ? NS_LAST : 0; /* Set last segment flag if end of the path */ *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ #if _FS_RPATH != 0 if ((di == 1 && lfn[di - 1] == '.') || (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { /* Is this segment a dot name? */ diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c index a38f3781f..313893d97 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -50,6 +50,20 @@ STATIC mp_vfs_mount_t *lookup_path(const char* path, mp_obj_t *path_out) { return vfs; } +// Strip off trailing slashes to please underlying libraries +STATIC mp_vfs_mount_t *lookup_dir_path(const char* path, mp_obj_t *path_out) { + const char *p_out; + mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out); + if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) { + size_t len = strlen(p_out); + while (len > 1 && p_out[len - 1] == '/') { + len--; + } + *path_out = mp_obj_new_str_of_type(&mp_type_str, (const byte*)p_out, len); + } + return vfs; +} + STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { if (vfs == MP_VFS_NONE) { // mount point not found @@ -69,7 +83,7 @@ STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_ void common_hal_os_chdir(const char* path) { mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); MP_STATE_VM(vfs_cur) = vfs; if (vfs == MP_VFS_ROOT) { // If we change to the root dir and a VFS is mounted at the root then @@ -93,7 +107,7 @@ mp_obj_t common_hal_os_getcwd(void) { mp_obj_t common_hal_os_listdir(const char* path) { mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); mp_vfs_ilistdir_it_t iter; mp_obj_t iter_obj = MP_OBJ_FROM_PTR(&iter); @@ -120,7 +134,7 @@ mp_obj_t common_hal_os_listdir(const char* path) { void common_hal_os_mkdir(const char* path) { mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); if (vfs == MP_VFS_ROOT || (vfs != MP_VFS_NONE && !strcmp(mp_obj_str_get_str(path_out), "/"))) { mp_raise_OSError(MP_EEXIST); } @@ -146,7 +160,7 @@ void common_hal_os_rename(const char* old_path, const char* new_path) { void common_hal_os_rmdir(const char* path) { mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); mp_vfs_proxy_call(vfs, MP_QSTR_rmdir, 1, &path_out); } -- cgit v1.2.3 From 43f7ca7985768c974b6881957b21d687c34413ba Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 11:33:56 -0800 Subject: Incorporate feedback: * Clean up board defines. * Add flush on eject and stay ejected. * Swith back to NONE protocol for CDC. --- lib/tinyusb | 2 +- ports/atmel-samd/boards/arduino_zero/mpconfigboard.h | 2 +- .../boards/circuitplayground_express/mpconfigboard.h | 1 - ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h | 2 ++ ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h | 7 ++++--- ports/atmel-samd/boards/trinket_m0/mpconfigboard.h | 2 +- ports/atmel-samd/common-hal/microcontroller/Pin.c | 5 ----- supervisor/shared/external_flash/external_flash.h | 2 +- supervisor/shared/usb/usb_msc_flash.c | 12 +++++++++++- tools/gen_usb_descriptor.py | 4 ++-- 10 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 537a29273..299a2f12d 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 537a29273c08b1e047004e1bd71c37af82937dd4 +Subproject commit 299a2f12de2ddb76b9a488b23e7e562058faee90 diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h index 56e4dbcec..9a6256c68 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -5,7 +5,7 @@ #define MICROPY_HW_LED_TX &pin_PA27 #define MICROPY_HW_LED_RX &pin_PB03 -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA27) +#define MICROPY_PORT_A (PORT_PA27) #define MICROPY_PORT_B (PORT_PB03) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 6dfaf87e9..2ad13e81c 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -14,7 +14,6 @@ #define SPI_FLASH_CS_PIN &pin_PB22 // These are pins not to reset. -// PA24 and PA25 are USB. #define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h index 7dd4bf7c4..5869c01ff 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -9,7 +9,9 @@ #define SPI_FLASH_CS_PIN &pin_PA07 // These are pins not to reset. +// NeoPixel and for the display: Reset, Command or data, and Chip select #define MICROPY_PORT_A ( PORT_PA01 | PORT_PA12 | PORT_PA27 | PORT_PA28) +// Data and Clock for the display #define MICROPY_PORT_B ( PORT_PB22 | PORT_PB23 ) #define MICROPY_PORT_C ( 0 ) diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h index 28bb1f293..f08d129dc 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -1,8 +1,9 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Metro M0 Express" #define MICROPY_HW_MCU_NAME "samd21g18" -//#define MICROPY_HW_LED_TX &pin_PA27 -//#define MICROPY_HW_LED_RX &pin_PA31 +#define MICROPY_HW_LED_TX &pin_PA27 +// Comment this out if you have trouble connecting over SWD. It's one of the SWD pins. +#define MICROPY_HW_LED_RX &pin_PA31 #define MICROPY_HW_NEOPIXEL (&pin_PA30) @@ -15,7 +16,7 @@ #define SPI_FLASH_CS_PIN &pin_PA13 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h index 24f3004e9..c311f540c 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -5,7 +5,7 @@ #define MICROPY_HW_APA102_MOSI (&pin_PA00) #define MICROPY_HW_APA102_SCK (&pin_PA01) -#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 9af5aeaf7..7dd9c6b09 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -53,12 +53,7 @@ void reset_all_pins(void) { // Do not full reset USB or SWD lines. pin_mask[0] &= ~(PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31); - #ifdef SAMD21 - pin_mask[0] &= ~(PORT_PA31); - #endif - for (uint32_t i = 0; i < PORT_COUNT; i++) { - pin_mask[i] &= ~(PORT_PA31); pin_mask[i] &= ~never_reset_pins[i]; } diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h index 852d183a7..72b619a2a 100644 --- a/supervisor/shared/external_flash/external_flash.h +++ b/supervisor/shared/external_flash/external_flash.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 72dc40204..13b5c3966 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -38,6 +38,8 @@ #define MSC_FLASH_BLOCK_SIZE 512 +static bool ejected[1]; + // The root FS is always at the end of the list. static fs_user_mount_t* get_vfs(int lun) { // TODO(tannewt): Return the mount which matches the lun where 0 is the end @@ -60,7 +62,7 @@ static fs_user_mount_t* get_vfs(int lun) { // - READ10 and WRITE10 have their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) { const void* response = NULL; - uint16_t resplen = 0; + int32_t resplen = 0; switch ( scsi_cmd[0] ) { case SCSI_CMD_TEST_UNIT_READY: @@ -73,6 +75,9 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, if (current_mount == NULL) { resplen = -1; } + if (ejected[lun]) { + resplen = -1; + } } break; @@ -96,6 +101,11 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, if (current_mount == NULL) { resplen = -1; } + if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) { + resplen = -1; + } else { + ejected[lun] = true; + } } } } diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index b50c0798f..2cb06ec2f 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -80,7 +80,7 @@ cdc_comm_interface = standard.InterfaceDescriptor( description="CDC comm", bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, + bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, iInterface=StringIndex.index("CircuitPython CDC control"), subdescriptors=[ cdc.Header( @@ -254,7 +254,7 @@ cdc_iad = standard.InterfaceAssociationDescriptor( bInterfaceCount=len(cdc_interfaces), bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bFunctionProtocol=cdc.CDC_PROTOCOL_V25TER) # TODO(tannewt): can this be NONE (aka 0)? + bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) # audio_iad = standard.InterfaceAssociationDescriptor( # description="Audio IAD", -- cgit v1.2.3 From 355abc835ea75715b4dea38604ef64f8c4eeaa0f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 16:41:08 -0800 Subject: Fix output overflow and make help translatable --- lib/utils/stdout_helpers.c | 16 ++++- locale/circuitpython.pot | 101 ++++++++++++++++-------------- locale/de_DE.po | 130 +++++++++++++++++++++------------------ locale/en_US.po | 101 ++++++++++++++++-------------- locale/es.po | 122 ++++++++++++++++++++----------------- locale/fil.po | 122 ++++++++++++++++++++----------------- locale/fr.po | 132 ++++++++++++++++++++++------------------ locale/it_IT.po | 130 +++++++++++++++++++++------------------ locale/pt_BR.po | 130 +++++++++++++++++++++------------------ ports/atmel-samd/mpconfigport.h | 1 - ports/nrf/mpconfigport.h | 1 - py/builtinhelp.c | 14 ++++- py/makeqstrdata.py | 3 +- shared-bindings/help.c | 11 ---- supervisor/shared/serial.c | 12 ++-- 15 files changed, 564 insertions(+), 462 deletions(-) diff --git a/lib/utils/stdout_helpers.c b/lib/utils/stdout_helpers.c index 3de119757..4323e8a08 100644 --- a/lib/utils/stdout_helpers.c +++ b/lib/utils/stdout_helpers.c @@ -12,11 +12,21 @@ // Send "cooked" string of given length, where every occurrence of // LF character is replaced with CR LF. void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { - while (len--) { - if (*str == '\n') { + bool last_cr = false; + while (len > 0) { + size_t i = 0; + if (str[0] == '\n' && !last_cr) { mp_hal_stdout_tx_strn("\r", 1); + i = 1; } - mp_hal_stdout_tx_strn(str++, 1); + // Lump all characters on the next line together. + while((last_cr || str[i] != '\n') && i < len) { + last_cr = str[i] == '\r'; + i++; + } + mp_hal_stdout_tx_strn(str, i); + str = &str[i]; + len -= i; } } diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index b15fe38b1..34467c7b5 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -151,70 +151,70 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr "" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "" -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "" -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "" @@ -359,7 +359,7 @@ msgid "Not enough pins available" msgstr "" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -403,7 +403,7 @@ msgid "No TX pin" msgstr "" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "" @@ -463,30 +463,10 @@ msgstr "" msgid "calibration value out of range +/-127" msgstr "" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "" - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "" @@ -823,7 +803,7 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 msgid "All SPI peripherals are in use" msgstr "" @@ -958,6 +938,20 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +msgid "Plus any modules on the filesystem\n" +msgstr "" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "" @@ -2440,27 +2434,27 @@ msgstr "" msgid "Clock stretch too long" msgstr "" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "" -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "" -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "" @@ -2494,6 +2488,10 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "" + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "" @@ -2501,3 +2499,16 @@ msgstr "" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "" + +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 2ff7acb87..7451d9b2a 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "ungültige argumente" msgid "script compilation not supported" msgstr "kompilieren von Skripten ist nicht unterstützt" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " Ausgabe:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,45 +163,45 @@ msgstr "" "Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " "auszuführen oder verbinde dich mit der REPL um zu deaktivieren.\n" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Sicherheitsmodus aktiv! Automatisches Neuladen ist deaktiviert.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "Automatisches Neuladen ist deaktiviert.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "WARNUNG: Der Dateiname deines codes hat zwei Dateityperweiterungen\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "Du hast das Starten im Sicherheitsmodus ausgelöst durch " -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Zum beenden bitte resette das board ohne " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "Sicherheitsmodus aktiv, etwas wirklich schlechtes ist passiert.\n" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "CircuitPython ist abgestürzt. Ups!\n" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Bitte erstelle ein issue hier mit dem Inhalt deines CIRCUITPY-speichers:\n" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -209,7 +209,7 @@ msgstr "" "Die Stromversorgung des Mikrocontrollers ist eingebrochen. Stelle sicher," "dass deine Stromversorgung\n" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -217,13 +217,13 @@ msgstr "" "genug Strom für den ganzen Schaltkreis liefert und drücke reset (nach dem " "sicheren Auswerfen von CIRCUITPY.)\n" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Drücke eine Taste um dich mit der REPL zu verbinden. Drücke Strg-D zum neu " "laden" -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "soft reboot\n" @@ -368,7 +368,7 @@ msgid "Not enough pins available" msgstr "Nicht genug Pins vorhanden" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -412,7 +412,7 @@ msgid "No TX pin" msgstr "Kein TX Pin" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "Pull up im Ausgabemodus nicht möglich" @@ -472,30 +472,10 @@ msgstr "Ein Hardware Interrupt Kanal wird schon benutzt" msgid "calibration value out of range +/-127" msgstr "Kalibrierwert nicht im Bereich von +/-127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "Kann '/' nicht remounten when USB aktiv ist" - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Keine freien GCLKs" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Buffergröße falsch, sollte %d bytes sein." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "USB beschäftigt" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "USB Fehler" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "Pin %q hat keine ADC Funktion" @@ -837,7 +817,7 @@ msgstr "Ungültiger UUID-Parameter" msgid "All I2C peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Alle timer werden benutzt" @@ -976,6 +956,21 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Dateisystem kann nicht wieder gemounted werden." + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "" @@ -2463,27 +2458,27 @@ msgstr "" msgid "Clock stretch too long" msgstr "" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "" -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "" -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "" @@ -2518,6 +2513,10 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "Kann '/' nicht remounten when USB aktiv ist" + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "" @@ -2526,32 +2525,45 @@ msgstr "" msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffergröße falsch, sollte %d bytes sein." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB beschäftigt" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "USB Fehler" + #~ msgid "Invalid Service type" #~ msgstr "Ungültiger Diensttyp" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "Kann UUID in das advertisement packet kodieren." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Kann PPCP Parameter nicht setzen." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." #~ msgid "Can not encode UUID, to check length." #~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." + #~ msgid "Can not apply device name in the stack." #~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." -#~ msgid "Can not add Characteristic." -#~ msgstr "Kann das Merkmal nicht hinzufügen." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" #~ msgid "Can not add Service." #~ msgstr "Kann den Dienst nicht hinzufügen." -#~ msgid "Can not query for the device address." -#~ msgstr "Kann nicht nach der Geräteadresse suchen." - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Kann PPCP Parameter nicht setzen." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Kann GAP Parameter nicht anwenden." +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." diff --git a/locale/en_US.po b/locale/en_US.po index e3a1062e0..e7bcf1c08 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 15:57-0800\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,70 +151,70 @@ msgstr "" msgid "script compilation not supported" msgstr "" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr "" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "" -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "" -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "" @@ -359,7 +359,7 @@ msgid "Not enough pins available" msgstr "" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -403,7 +403,7 @@ msgid "No TX pin" msgstr "" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "" @@ -463,30 +463,10 @@ msgstr "" msgid "calibration value out of range +/-127" msgstr "" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "" - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "" @@ -823,7 +803,7 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 msgid "All SPI peripherals are in use" msgstr "" @@ -958,6 +938,20 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +msgid "Plus any modules on the filesystem\n" +msgstr "" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "" @@ -2440,27 +2434,27 @@ msgstr "" msgid "Clock stretch too long" msgstr "" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "" -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "" -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "" @@ -2494,6 +2488,10 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "" + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "" @@ -2501,3 +2499,16 @@ msgstr "" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "" + +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "" diff --git a/locale/es.po b/locale/es.po index 340741e69..e9e97842a 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "script de compilación no soportado" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " salida:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,49 +163,49 @@ msgstr "" "Auto-reload habilitado. Simplemente guarda los archivos via USB para " "ejecutarlos o entra al REPL para desabilitarlos.\n" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "Auto-recarga deshabilitada.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "Solicitaste iniciar en modo seguro por " -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Para salir, por favor reinicia la tarjeta sin " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Estás ejecutando en modo seguro, lo cual significa que algo realmente malo " "ha sucedido.\n" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "Parece que nuestro código CircuitPython dejó de funcionar. Whoops!\n" -#: main.c:262 +#: main.c:263 #, fuzzy msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Por favor registra un issue en el siguiente URL con los contenidos de tu " "unidad de almacenamiento CIRCUITPY:\n" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -213,7 +213,7 @@ msgstr "" "La alimentación del microcontrolador cayó. Por favor asegurate de que tu " "fuente de alimentación provee\n" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -221,12 +221,12 @@ msgstr "" "suficiente poder para todo el circuito y presiona reset (después de expulsar " "CIRCUITPY).\n" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar." -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "reinicio suave\n" @@ -371,7 +371,7 @@ msgid "Not enough pins available" msgstr "No hay suficientes pines disponibles" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -415,7 +415,7 @@ msgid "No TX pin" msgstr "Sin pin TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "No puede ser pull mientras este en modo de salida" @@ -475,30 +475,10 @@ msgstr "El canal EXTINT ya está siendo utilizado" msgid "calibration value out of range +/-127" msgstr "Valor de calibración fuera del rango +/-127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "No se puede volver a montar '/' cuando el USB esta activo." - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Sin GCLKs libres" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "USB ocupado" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "Error USB" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "Pin %q no tiene capacidades de ADC" @@ -837,7 +817,7 @@ msgstr "Parámetro UUID inválido" msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo usados" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 msgid "All SPI peripherals are in use" msgstr "Todos los timers están siendo usados" @@ -972,6 +952,21 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Incapaz de montar de nuevo el sistema de archivos" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "" @@ -2457,27 +2452,27 @@ msgstr "" msgid "Clock stretch too long" msgstr "" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "" -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "" -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "" @@ -2511,6 +2506,10 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "No se puede volver a montar '/' cuando el USB esta activo." + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "" @@ -2519,35 +2518,48 @@ msgstr "" msgid "too many arguments provided with the given format" msgstr "" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB ocupado" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "Error USB" + #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Baud rate demasiado alto para este periférico SPI" #~ msgid "Invalid Service type" #~ msgstr "Tipo de Servicio inválido" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Se puede codificar el UUID en el paquete de anuncio." #~ msgid "Can not encode UUID, to check length." #~ msgstr "No se puede codificar el UUID, para revisar la longitud." +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" + #~ msgid "Can not apply device name in the stack." #~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." #~ msgid "Can not add Characteristic." #~ msgstr "No se puede agregar la Característica." -#~ msgid "Can not add Service." -#~ msgstr "No se puede agregar el Servicio." - -#~ msgid "Can not query for the device address." -#~ msgstr "No se puede consultar la dirección del dispositivo." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." #~ msgid "Cannot set PPCP parameters." #~ msgstr "No se pueden establecer los parámetros PPCP." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "No se pueden aplicar los parámetros GAP." +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." diff --git a/locale/fil.po b/locale/fil.po index 2a84b506e..1dc5c1ca4 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -151,11 +151,11 @@ msgstr "mali ang mga argumento" msgid "script compilation not supported" msgstr "script kompilasyon hindi supportado" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " output:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,48 +163,48 @@ msgstr "" "Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB " "para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Tumatakbo sa safe mode! Awtomatikong pag re-reload ay OFF.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "Awtomatikong pag re-reload ay OFF.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Para lumabas, paki-reset ang board na wala ang " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Ikaw ay tumatakbo sa safe mode, ang ibig sabihin nito ay may masamang " "nangyari.\n" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "Mukhang ang core CircuitPython code ay nag-crash ng malakas. Aray!\n" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Mag-file ng isang isyu dito gamit ang mga nilalaman ng iyong CIRCUITPY " "drive:\n" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -212,7 +212,7 @@ msgstr "" "Ang kapangyarihan ng mikrokontroller ay bumaba. Mangyaring suriin ang power " "supply \n" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -220,13 +220,13 @@ msgstr "" "ay nagbibigay ng sapat na power para sa buong circuit at i-press ang reset " "(pagkatapos i-eject ang CIRCUITPY).\n" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Pindutin ang anumang key upang ipasok ang REPL. Gamitin ang CTRL-D upang i-" "reload." -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "malambot na reboot\n" @@ -371,7 +371,7 @@ msgid "Not enough pins available" msgstr "Hindi sapat ang magagamit na pins" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -415,7 +415,7 @@ msgid "No TX pin" msgstr "Walang TX pin" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "Hindi makakakuha ng pull habang nasa output mode" @@ -475,30 +475,10 @@ msgstr "Isang channel ng hardware interrupt ay ginagamit na" msgid "calibration value out of range +/-127" msgstr "ang halaga ng pagkakalibrate ay wala sa sakop +/-127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "Hindi ma-remount '/' kapag aktibo ang USB." - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Walang libreng GCLKs" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Mali ang size ng buffer. Dapat %d bytes." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "Busy ang USB" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "May pagkakamali ang USB" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "Walang kakayahang ADC ang pin %q" @@ -840,7 +820,7 @@ msgstr "Mali ang UUID parameter" msgid "All I2C peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Lahat ng timer ginagamit" @@ -983,6 +963,21 @@ msgstr "masamang typecode" msgid "bad compile mode" msgstr "masamang mode ng compile" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Hindi ma-remount ang filesystem" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "hindi maaring isagawa ang relative import" @@ -2510,27 +2505,27 @@ msgstr "Mali ang file" msgid "Clock stretch too long" msgstr "Masyadong mahaba ang Clock stretch" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "Nabigo sa pag init ng Clock pin." -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "Hindi ma-initialize ang MOSI pin." -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "Hindi ma-initialize ang MISO pin." -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "Hindi maaring isulat kapag walang MOSI pin." -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "Hindi maaring mabasa kapag walang MISO pin." -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "Hindi maaaring ilipat kapag walang MOSI at MISO pin." @@ -2566,6 +2561,10 @@ msgstr "" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "Hindi ma-remount '/' kapag aktibo ang USB." + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "Ang 'S' at 'O' ay hindi suportadong uri ng format" @@ -2574,6 +2573,19 @@ msgstr "Ang 'S' at 'O' ay hindi suportadong uri ng format" msgid "too many arguments provided with the given format" msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Mali ang size ng buffer. Dapat %d bytes." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "Busy ang USB" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "May pagkakamali ang USB" + #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "ang palette ay dapat 32 bytes ang haba" @@ -2581,29 +2593,29 @@ msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" #~ msgid "Invalid Service type" #~ msgstr "Mali ang tipo ng serbisyo" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" - #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Maaring i-encode ang UUID sa advertisement packet." #~ msgid "Can not encode UUID, to check length." #~ msgstr "Hindi ma-encode UUID, para suriin ang haba." +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" + #~ msgid "Can not apply device name in the stack." #~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." #~ msgid "Can not add Characteristic." #~ msgstr "Hindi mabasa and Characteristic." -#~ msgid "Can not add Service." -#~ msgstr "Hindi maidaragdag ang serbisyo." - -#~ msgid "Can not query for the device address." -#~ msgstr "Hindi maaaring mag-query para sa address ng device." +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." #~ msgid "Cannot set PPCP parameters." #~ msgstr "Hindi ma-set ang PPCP parameters." -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Hindi ma-apply ang GAP parameters." +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." diff --git a/locale/fr.po b/locale/fr.po index b6d7d4855..71962f610 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -150,11 +150,11 @@ msgstr "arguments invalides" msgid "script compilation not supported" msgstr "compilation du script non supporté" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " sortie:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -162,46 +162,46 @@ msgstr "" "Auto-chargement activé. Copiez simplement les fichiers en USB pour les " "lancer ou entrez sur REPL pour le désactiver.\n" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Mode sans-échec. Auto-rechargement désactivé.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "Auto-rechargement désactivé.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Mode sans-échec! Le code sauvegardé ne s'éxecute pas.\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "Vous avez demandé à démarrer en mode sans-échec par " -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Pour quitter, redémarrez la carte SVP sans " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Vous êtes en mode sans-échec ce qui signifie que quelque chose demauvais est " "arrivé.\n" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "Il semblerait que votre code CircuitPython a durement planté. Oups!\n" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "SVP, remontez le problème là avec le contenu du lecteur CIRCUITPY:\n" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -209,7 +209,7 @@ msgstr "" "L'alimentation du microcontroleur a chuté. Merci de vérifier que votre " "alimentation fournit\n" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -217,11 +217,11 @@ msgstr "" "assez de puissance pour l'ensemble du circuit et appuyez sur 'reset' (après " "avoir éjecter CIRCUITPY).\n" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "redémarrage logiciel\n" @@ -366,7 +366,7 @@ msgid "Not enough pins available" msgstr "Pas assez de broches disponibles" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -410,7 +410,7 @@ msgid "No TX pin" msgstr "Pas de broche TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "Ne peux être tirer ('pull') en mode 'output'" @@ -471,30 +471,10 @@ msgstr "Un canal d'interruptions est déjà utilisé" msgid "calibration value out of range +/-127" msgstr "valeur de calibration hors gamme +/-127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "'/' ne peut être remonté quand l'USB est actif." - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Pas de GCLK libre" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Tampon de taille incorrect. Devrait être de %d octets." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "USB occupé" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "Erreur USB" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "La broche %q n'a pas de convertisseur analogique-digital" @@ -835,7 +815,7 @@ msgstr "Paramètre UUID invalide" msgid "All I2C peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 #, fuzzy msgid "All SPI peripherals are in use" msgstr "Tous les timers sont utilisés" @@ -976,6 +956,21 @@ msgstr "mauvais code type" msgid "bad compile mode" msgstr "mauvais mode de compilation" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Impossible de remonter le système de fichiers" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "ne peut pas réaliser un import relatif" @@ -2508,27 +2503,27 @@ msgstr "Fichier invalide" msgid "Clock stretch too long" msgstr "Période de l'horloge trop longue" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "Echec de l'init. de la broche d'horloge" -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "Echec de l'init. de la broche MOSI" -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "Echec de l'init. de la broche MISO" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "Impossible d'écrire sans broche MOSI." -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "Impossible de lire sans broche MISO." -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "Pas de transfert sans broches MOSI et MISO" @@ -2564,6 +2559,10 @@ msgstr "Seul le format Windows, BMP non compressé, est supporté %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Seul les BMP 'true color' (24 bpp ou plus) sont supportés %x" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "'/' ne peut être remonté quand l'USB est actif." + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "'S' et 'O' ne sont pas des types de format supportés" @@ -2572,34 +2571,47 @@ msgstr "'S' et 'O' ne sont pas des types de format supportés" msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Tampon de taille incorrect. Devrait être de %d octets." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB occupé" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "Erreur USB" + #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "palettre doit être displayio.Palette" -#, fuzzy -#~ msgid "value_size must be power of two" -#~ msgstr "value_size est une puissance de deux" +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" -#~ msgid "Invalid Service type" -#~ msgstr "Type de service invalide" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" #~ msgid "Can not encode UUID, to check length." #~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" + #~ msgid "Can not apply device name in the stack." #~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" -#~ msgid "Can not add Characteristic." -#~ msgstr "Impossible d'ajouter la Characteristic." +#, fuzzy +#~ msgid "value_size must be power of two" +#~ msgstr "value_size est une puissance de deux" #~ msgid "Can not add Service." #~ msgstr "Impossible d'ajouter le Service" -#~ msgid "Can not query for the device address." -#~ msgstr "Impossible d'obtenir l'adresse du périphérique" - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossible d'appliquer les paramètres PPCP" - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossible d'appliquer les paramètres GAP" +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." diff --git a/locale/it_IT.po b/locale/it_IT.po index a90a3aa1f..4acdb39f7 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -151,11 +151,11 @@ msgstr "argomenti non validi" msgid "script compilation not supported" msgstr "compilazione dello scrip non suportata" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " output:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" @@ -163,50 +163,50 @@ msgstr "" "L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL " "per disabilitarlo.\n" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Modalità sicura in esecuzione! Auto-reload disattivato.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "Auto-reload disattivato.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENZIONE: Il nome del sorgente ha due estensioni\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "È stato richiesto l'avvio in modalità sicura da " -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Per uscire resettare la scheda senza " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" "Sei nella modalità sicura che significa che qualcosa di molto brutto è " "successo.\n" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" "Sembra che il codice del core di CircuitPython sia crashato malamente. " "Whoops!\n" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" "Ti preghiamo di compilare una issue con il contenuto del tuo drie " "CIRCUITPY:\n" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" @@ -214,7 +214,7 @@ msgstr "" "La potenza del microcontrollore è calata. Assicurati che l'alimentazione sia " "attaccata correttamente\n" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" @@ -222,12 +222,12 @@ msgstr "" "abbastanza potenza per l'intero circuito e premere reset (dopo aver espulso " "CIRCUITPY).\n" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Premi un qualunque tasto per entrare nel REPL. Usa CTRL-D per ricaricare." -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "soft reboot\n" @@ -374,7 +374,7 @@ msgid "Not enough pins available" msgstr "Non sono presenti abbastanza pin" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -418,7 +418,7 @@ msgid "No TX pin" msgstr "Nessun pin TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "" @@ -479,30 +479,10 @@ msgstr "Un canale di interrupt hardware è già in uso" msgid "calibration value out of range +/-127" msgstr "valore di calibrazione fuori intervallo +/-127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Nessun GCLK libero" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "USB occupata" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "Errore USB" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "Il pin %q non ha capacità ADC" @@ -841,7 +821,7 @@ msgstr "Parametro UUID non valido" msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 msgid "All SPI peripherals are in use" msgstr "Tutte le periferiche SPI sono in uso" @@ -983,6 +963,21 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Imposssibile rimontare il filesystem" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "impossibile effettuare l'importazione relativa" @@ -2497,27 +2492,27 @@ msgstr "File non valido" msgid "Clock stretch too long" msgstr "" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "Inizializzazione del pin di clock fallita." -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "inizializzazione del pin MOSI fallita." -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "inizializzazione del pin MISO fallita." -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "Impossibile scrivere senza pin MOSI." -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "Impossibile leggere senza pin MISO." -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "Impossibile trasferire senza i pin MOSI e MISO." @@ -2551,6 +2546,10 @@ msgstr "Formato solo di Windows, BMP non compresso supportato %d" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Solo BMP true color (24 bpp o superiore) sono supportati %x" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' non sono formati supportati" @@ -2559,32 +2558,45 @@ msgstr "'S' e 'O' non sono formati supportati" msgid "too many arguments provided with the given format" msgstr "troppi argomenti forniti con il formato specificato" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB occupata" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "Errore USB" + #~ msgid "Invalid Service type" #~ msgstr "Tipo di servizio non valido" -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." -#~ msgid "Can encode UUID into the advertisement packet." -#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." #~ msgid "Can not encode UUID, to check length." #~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + #~ msgid "Can not apply device name in the stack." #~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." -#~ msgid "Can not add Characteristic." -#~ msgstr "Non è possibile aggiungere Characteristic." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" #~ msgid "Can not add Service." #~ msgstr "Non è possibile aggiungere Service." -#~ msgid "Can not query for the device address." -#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Impossibile impostare i parametri PPCP." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Impossibile applicare i parametri GAP." +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 4ee9a32ff..2400b6a13 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 14:10-0500\n" +"POT-Creation-Date: 2018-11-09 16:20-0800\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -151,70 +151,70 @@ msgstr "argumentos inválidos" msgid "script compilation not supported" msgstr "compilação de script não suportada" -#: main.c:153 +#: main.c:154 msgid " output:\n" msgstr " saída:\n" -#: main.c:167 main.c:240 +#: main.c:168 main.c:241 msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -#: main.c:169 +#: main.c:170 msgid "Running in safe mode! Auto-reload is off.\n" msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" -#: main.c:171 main.c:242 +#: main.c:172 main.c:243 msgid "Auto-reload is off.\n" msgstr "A atualização automática está desligada.\n" -#: main.c:185 +#: main.c:186 msgid "Running in safe mode! Not running saved code.\n" msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" -#: main.c:201 +#: main.c:202 msgid "WARNING: Your code filename has two extensions\n" msgstr "AVISO: Seu arquivo de código tem duas extensões\n" -#: main.c:249 +#: main.c:250 msgid "You requested starting safe mode by " msgstr "Você solicitou o início do modo de segurança" -#: main.c:252 +#: main.c:253 msgid "To exit, please reset the board without " msgstr "Para sair, por favor, reinicie a placa sem " -#: main.c:259 +#: main.c:260 msgid "" "You are running in safe mode which means something really bad happened.\n" msgstr "" -#: main.c:261 +#: main.c:262 msgid "Looks like our core CircuitPython code crashed hard. Whoops!\n" msgstr "" -#: main.c:262 +#: main.c:263 msgid "Please file an issue here with the contents of your CIRCUITPY drive:\n" msgstr "" -#: main.c:265 +#: main.c:266 msgid "" "The microcontroller's power dipped. Please make sure your power supply " "provides\n" msgstr "" -#: main.c:266 +#: main.c:267 msgid "" "enough power for the whole circuit and press reset (after ejecting " "CIRCUITPY).\n" msgstr "" -#: main.c:270 +#: main.c:271 msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" -#: main.c:426 +#: main.c:429 msgid "soft reboot\n" msgstr "" @@ -359,7 +359,7 @@ msgid "Not enough pins available" msgstr "Não há pinos suficientes disponíveis" #: ports/atmel-samd/common-hal/busio/I2C.c:78 -#: ports/atmel-samd/common-hal/busio/SPI.c:132 +#: ports/atmel-samd/common-hal/busio/SPI.c:171 #: ports/atmel-samd/common-hal/busio/UART.c:119 #: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c:45 #: ports/nrf/common-hal/busio/I2C.c:82 @@ -403,7 +403,7 @@ msgid "No TX pin" msgstr "Nenhum pino TX" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c:170 -#: ports/nrf/common-hal/digitalio/DigitalInOut.c:142 +#: ports/nrf/common-hal/digitalio/DigitalInOut.c:147 msgid "Cannot get pull while in output mode" msgstr "" @@ -463,30 +463,10 @@ msgstr "Um canal de interrupção de hardware já está em uso" msgid "calibration value out of range +/-127" msgstr "Valor de calibração fora do intervalo +/- 127" -#: ports/atmel-samd/common-hal/storage/__init__.c:48 -msgid "Cannot remount '/' when USB is active." -msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." - #: ports/atmel-samd/common-hal/touchio/TouchIn.c:75 msgid "No free GCLKs" msgstr "Não há GCLKs livre" -#: ports/atmel-samd/common-hal/usb_hid/Device.c:78 -#: ports/nrf/common-hal/usb_hid/Device.c:45 -#, c-format -msgid "Buffer incorrect size. Should be %d bytes." -msgstr "Buffer de tamanho incorreto. Deve ser %d bytes." - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:53 -msgid "USB Busy" -msgstr "USB ocupada" - -#: ports/atmel-samd/common-hal/usb_hid/Device.c:82 -#: ports/nrf/common-hal/usb_hid/Device.c:59 -msgid "USB Error" -msgstr "Erro na USB" - #: ports/esp8266/common-hal/analogio/AnalogIn.c:43 msgid "Pin %q does not have ADC capabilities" msgstr "Pino %q não tem recursos de ADC" @@ -824,7 +804,7 @@ msgstr "Parâmetro UUID inválido" msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" -#: ports/nrf/common-hal/busio/SPI.c:115 +#: ports/nrf/common-hal/busio/SPI.c:133 msgid "All SPI peripherals are in use" msgstr "Todos os periféricos SPI estão em uso" @@ -962,6 +942,21 @@ msgstr "" msgid "bad compile mode" msgstr "" +#: py/builtinhelp.c:137 +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Não é possível remontar o sistema de arquivos" + +#: py/builtinhelp.c:183 +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + #: py/builtinimport.c:336 msgid "cannot perform relative import" msgstr "" @@ -2449,27 +2444,27 @@ msgstr "Arquivo inválido" msgid "Clock stretch too long" msgstr "Clock se estendeu por tempo demais" -#: shared-module/bitbangio/SPI.c:45 +#: shared-module/bitbangio/SPI.c:44 msgid "Clock pin init failed." msgstr "Inicialização do pino de Clock falhou." -#: shared-module/bitbangio/SPI.c:51 +#: shared-module/bitbangio/SPI.c:50 msgid "MOSI pin init failed." msgstr "Inicialização do pino MOSI falhou." -#: shared-module/bitbangio/SPI.c:62 +#: shared-module/bitbangio/SPI.c:61 msgid "MISO pin init failed." msgstr "Inicialização do pino MISO falhou" -#: shared-module/bitbangio/SPI.c:122 +#: shared-module/bitbangio/SPI.c:121 msgid "Cannot write without MOSI pin." msgstr "Não é possível ler sem um pino MOSI" -#: shared-module/bitbangio/SPI.c:177 +#: shared-module/bitbangio/SPI.c:176 msgid "Cannot read without MISO pin." msgstr "Não é possível ler sem o pino MISO." -#: shared-module/bitbangio/SPI.c:241 +#: shared-module/bitbangio/SPI.c:240 msgid "Cannot transfer without MOSI and MISO pins." msgstr "Não é possível transferir sem os pinos MOSI e MISO." @@ -2503,6 +2498,10 @@ msgstr "Apenas formato Windows, BMP descomprimido suportado" msgid "Only true color (24 bpp or higher) BMP supported %x" msgstr "Apenas cores verdadeiras (24 bpp ou maior) BMP suportadas" +#: shared-module/storage/__init__.c:155 +msgid "Cannot remount '/' when USB is active." +msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." + #: shared-module/struct/__init__.c:39 msgid "'S' and 'O' are not supported format types" msgstr "'S' e 'O' não são tipos de formato suportados" @@ -2511,32 +2510,45 @@ msgstr "'S' e 'O' não são tipos de formato suportados" msgid "too many arguments provided with the given format" msgstr "Muitos argumentos fornecidos com o formato dado" +#: shared-module/usb_hid/Device.c:45 +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffer de tamanho incorreto. Deve ser %d bytes." + +#: shared-module/usb_hid/Device.c:53 +msgid "USB Busy" +msgstr "USB ocupada" + +#: shared-module/usb_hid/Device.c:59 +msgid "USB Error" +msgstr "Erro na USB" + #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" -#~ msgid "Invalid Service type" -#~ msgstr "Tipo de serviço inválido" +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possível consultar o endereço do dispositivo." -#~ msgid "Can not apply advertisement data. status: 0x%02x" -#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possível definir parâmetros PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possível aplicar parâmetros GAP." #~ msgid "Can encode UUID into the advertisement packet." #~ msgstr "Pode codificar o UUID no pacote de anúncios." +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possível aplicar dados de anúncio. status: 0x%02x" + #~ msgid "Can not apply device name in the stack." #~ msgstr "Não é possível aplicar o nome do dispositivo na pilha." -#~ msgid "Can not add Characteristic." -#~ msgstr "Não é possível adicionar Característica." +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" #~ msgid "Can not add Service." #~ msgstr "Não é possível adicionar o serviço." -#~ msgid "Can not query for the device address." -#~ msgstr "Não é possível consultar o endereço do dispositivo." - -#~ msgid "Cannot set PPCP parameters." -#~ msgstr "Não é possível definir parâmetros PPCP." - -#~ msgid "Cannot apply GAP parameters." -#~ msgstr "Não é possível aplicar parâmetros GAP." +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possível adicionar Característica." diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 3b95aefa9..392b0773e 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -37,7 +37,6 @@ #define MICROPY_PY_BUILTINS_ENUMERATE (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_MODULES (1) -#define MICROPY_PY_BUILTINS_HELP_TEXT circuitpython_help_text #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY_BUILTINS_FILTER (1) #define MICROPY_PY_BUILTINS_SET (1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index c9c03427f..7b2b8f1d1 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -90,7 +90,6 @@ #define MICROPY_PY_BUILTINS_COMPILE (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_MODULES (1) -#define MICROPY_PY_BUILTINS_HELP_TEXT circuitpython_help_text #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (0) diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 4cea7e6d5..9a3407a16 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -27,6 +27,7 @@ #include #include +#include "genhdr/mpversion.h" #include "py/builtin.h" #include "py/mpconfig.h" #include "py/objmodule.h" @@ -133,7 +134,10 @@ STATIC void mp_help_print_modules(void) { } // let the user know there may be other modules available from the filesystem - mp_print_str(MP_PYTHON_PRINTER, "Plus any modules on the filesystem\n"); + const compressed_string_t* compressed = translate("Plus any modules on the filesystem\n"); + char decompressed[compressed->length]; + decompress(compressed, decompressed); + mp_print_str(MP_PYTHON_PRINTER, decompressed); } #endif @@ -174,8 +178,12 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { STATIC mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { - // print a general help message - mp_print_str(MP_PYTHON_PRINTER, MICROPY_PY_BUILTINS_HELP_TEXT); + // print a general help message. Translate only works on single strings on one line. + const compressed_string_t* compressed = + translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"); + char decompressed[compressed->length]; + decompress(compressed, decompressed); + mp_printf(MP_PYTHON_PRINTER, decompressed, MICROPY_GIT_TAG); } else { // try to print something sensible about the given object mp_help_print_obj(args[0]); diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index b0a043ee3..5b5ec1c37 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -349,8 +349,7 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns): total_text_compressed_size += len(compressed) decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8") for c in C_ESCAPES: - decompressed.replace(c, C_ESCAPES[c]) - #print("// \"{}\"".format(translation)) + decompressed = decompressed.replace(c, C_ESCAPES[c]) print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed)) total_text_size += len(translation.encode("utf-8")) diff --git a/shared-bindings/help.c b/shared-bindings/help.c index 78301a91a..e0770ff3c 100644 --- a/shared-bindings/help.c +++ b/shared-bindings/help.c @@ -24,8 +24,6 @@ * THE SOFTWARE. */ -#include "genhdr/mpversion.h" - //| :func:`help` - Built-in method to provide helpful information //| ============================================================== //| @@ -34,12 +32,3 @@ //| Prints a help method about the given object. When ``object`` is none, //| prints general port information. //| - -// TODO(tannewt): Figure out how to translate this. Its weird because its a global string. - -const char circuitpython_help_text[] = - "Welcome to Adafruit CircuitPython " MICROPY_GIT_TAG "!\r\n" - "\r\n" - "Please visit learn.adafruit.com/category/circuitpython for project guides.\r\n" - "\r\n" - "To list built-in modules please do `help(\"modules\")`.\r\n"; diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 058c4a7a4..cd20b5c26 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -47,10 +47,14 @@ bool serial_bytes_available(void) { return tud_cdc_available() > 0; } -void serial_write(const char* text) { - tud_cdc_write(text, strlen(text)); +void serial_write_substring(const char* text, uint32_t length) { + uint32_t count = 0; + while (count < length) { + count += tud_cdc_write(text + count, length - count); + usb_background(); + } } -void serial_write_substring(const char* text, uint32_t length) { - tud_cdc_write(text, length); +void serial_write(const char* text) { + serial_write_substring(text, strlen(text)); } -- cgit v1.2.3 From d012fd155338641f1d54d68d04410a848e07319d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 9 Nov 2018 17:06:55 -0800 Subject: Only write to usb when its around. --- supervisor/shared/serial.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index cd20b5c26..c57688ddc 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -48,6 +48,9 @@ bool serial_bytes_available(void) { } void serial_write_substring(const char* text, uint32_t length) { + if (!tud_cdc_connected()) { + return; + } uint32_t count = 0; while (count < length) { count += tud_cdc_write(text + count, length - count); -- cgit v1.2.3 From ed9db807605e81a740e68e625bbe6b333581fcc0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 13 Nov 2018 10:43:18 -0800 Subject: Switch SAMD51 back to -Os It messes up neopixel timing otherwise. Fixes #1326 --- ports/atmel-samd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 552be92be..23fb39779 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -93,7 +93,7 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_C endif ifeq ($(CHIP_FAMILY), samd51) -CFLAGS += -O0 -DNDEBUG +CFLAGS += -Os -DNDEBUG # TinyUSB defines CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 endif -- cgit v1.2.3 From a3a690dc018ba70fe415def0216ab0bb9ef49d9c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 13 Nov 2018 10:56:00 -0800 Subject: Add pragma to ensure neopixel_write is always -Os --- ports/atmel-samd/common-hal/neopixel_write/__init__.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/atmel-samd/common-hal/neopixel_write/__init__.c b/ports/atmel-samd/common-hal/neopixel_write/__init__.c index b30ad47d4..57e963c91 100644 --- a/ports/atmel-samd/common-hal/neopixel_write/__init__.c +++ b/ports/atmel-samd/common-hal/neopixel_write/__init__.c @@ -48,6 +48,11 @@ } #endif +// Ensure this code is compiled with -Os. Any other optimization level may change the timing of it +// and break neopixels. +#pragma GCC push_options +#pragma GCC optimize ("Os") + uint64_t next_start_tick_ms = 0; uint32_t next_start_tick_us = 1000; @@ -183,3 +188,5 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, mp_hal_enable_all_interrupts(); } + +#pragma GCC pop_options -- cgit v1.2.3 From 4ae4cc11e081926eb361cd9942188159efa97f9a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 13 Nov 2018 11:27:18 -0800 Subject: Clear Trellis NeoPixels on board reset. This makes it easier to change code in cases where the pixels may cause a brownout. --- ports/atmel-samd/boards/trellis_m4_express/board.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/trellis_m4_express/board.c b/ports/atmel-samd/boards/trellis_m4_express/board.c index 0f60736a2..a9b5f8163 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/board.c +++ b/ports/atmel-samd/boards/trellis_m4_express/board.c @@ -24,9 +24,14 @@ * THE SOFTWARE. */ +#include + #include "boards/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" +#include "py/mpconfig.h" + +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" void board_init(void) { } @@ -36,4 +41,11 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { + uint8_t zeroes[96]; + memset(zeroes, 0, 96); + digitalio_digitalinout_obj_t neopixel; + common_hal_digitalio_digitalinout_construct(&neopixel, &pin_PA27); + common_hal_digitalio_digitalinout_switch_to_output(&neopixel, false, DRIVE_MODE_PUSH_PULL); + common_hal_neopixel_write(&neopixel, zeroes, 96); + common_hal_digitalio_digitalinout_deinit(&neopixel); } -- cgit v1.2.3 From c5aa2e93001436f6d63e3e9b7dff3c535397db1c Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Mon, 12 Nov 2018 16:16:47 +0100 Subject: Support OSError attributes This adds support for the OSError attributes : errno, strerror, filename and filename2. CPython only sets errno if 2 arguments has been passed in. This has not been implemented here. CPython OSError.args is capped at 2 items for backward compatibility reasons. This has not been implemented here. MICROPY_CPYTHON_COMPAT has to be enabled to get these attributes. mp_common_errno_to_str() has been extended to check mp_errno_to_str() as well. This is done to ease reuse for the strerror argument. --- py/moduerrno.c | 37 +++++++++++++++++++++++-------------- py/mperrno.h | 3 +-- py/objexcept.c | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/py/moduerrno.c b/py/moduerrno.c index 255c1a73e..c1feafaa1 100644 --- a/py/moduerrno.c +++ b/py/moduerrno.c @@ -136,19 +136,28 @@ const char* mp_errno_to_str(mp_obj_t errno_val) { #endif //MICROPY_PY_UERRNO -// For commonly encountered errors, return human readable strings -const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val) { - if (MP_OBJ_IS_SMALL_INT(errno_val)) { - switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) { - case EPERM: return translate("Permission denied"); - case ENOENT: return translate("No such file/directory"); - case EIO: return translate("Input/output error"); - case EACCES: return translate("Permission denied"); - case EEXIST: return translate("File exists"); - case ENODEV: return translate("Unsupported operation"); - case EINVAL: return translate("Invalid argument"); - case EROFS: return translate("Read-only filesystem"); - } +// For commonly encountered errors, return human readable strings, otherwise try errno name +const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len) { + if (!MP_OBJ_IS_SMALL_INT(errno_val)) { + return NULL; + } + + const compressed_string_t* desc = NULL; + switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) { + case EPERM: desc = translate("Permission denied"); break; + case ENOENT: desc = translate("No such file/directory"); break; + case EIO: desc = translate("Input/output error"); break; + case EACCES: desc = translate("Permission denied"); break; + case EEXIST: desc = translate("File exists"); break; + case ENODEV: desc = translate("Unsupported operation"); break; + case EINVAL: desc = translate("Invalid argument"); break; + case EROFS: desc = translate("Read-only filesystem"); break; } - return NULL; + if (desc != NULL && desc->length <= len) { + decompress(desc, buf); + return buf; + } + + const char *msg = mp_errno_to_str(errno_val); + return msg[0] != '\0' ? msg : NULL; } diff --git a/py/mperrno.h b/py/mperrno.h index 876b090b5..911a9b413 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -141,7 +141,6 @@ #endif const char* mp_errno_to_str(mp_obj_t errno_val); -// For commonly encountered errors, return compressed human readable strings -const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val); +const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len); #endif // MICROPY_INCLUDED_PY_MPERRNO_H diff --git a/py/objexcept.c b/py/objexcept.c index 1ddc2174e..c54e5fd4a 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -114,17 +114,11 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin return; } else if (o->args->len == 1) { // try to provide a nice OSError error message - if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { - const compressed_string_t* common = mp_common_errno_to_str(o->args->items[0]); - const char* msg; + if (MP_OBJ_IS_SMALL_INT(o->args->items[0]) && + mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(o->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { char decompressed[50]; - if (common != NULL && common->length <= 50) { - decompress(common, decompressed); - msg = decompressed; - } else { - msg = mp_errno_to_str(o->args->items[0]); - } - if (msg[0] != '\0') { + const char *msg = mp_common_errno_to_str(o->args->items[0], decompressed, sizeof(decompressed)); + if (msg != NULL) { mp_printf(print, "[Errno " INT_FMT "] %s", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), msg); return; } @@ -215,6 +209,31 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = MP_OBJ_FROM_PTR(self->args); } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { dest[0] = mp_obj_exception_get_value(self_in); + #if MICROPY_CPYTHON_COMPAT + } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { + if (attr == MP_QSTR_errno) { + dest[0] = mp_obj_exception_get_value(self_in); + } else if (attr == MP_QSTR_strerror) { + if (self->args->len > 1) { + dest[0] = self->args->items[1]; + } else if (self->args->len > 0) { + char decompressed[50]; + const char *msg = mp_common_errno_to_str(self->args->items[0], decompressed, sizeof(decompressed)); + if (msg != NULL) { + dest[0] = mp_obj_new_str(msg, strlen(msg)); + } else { + dest[0] = mp_const_none; + } + } else { + dest[0] = mp_const_none; + } + } else if (attr == MP_QSTR_filename) { + dest[0] = self->args->len > 2 ? self->args->items[2] : mp_const_none; + // skip winerror + } else if (attr == MP_QSTR_filename2) { + dest[0] = self->args->len > 4 ? self->args->items[4] : mp_const_none; + } + #endif } } -- cgit v1.2.3 From 704d0c606bc4ade60fb8d650d29d74fe17e47463 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Mon, 12 Nov 2018 16:17:07 +0100 Subject: samd51: Support more uerrno errno values Use the default MICROPY_PY_UERRNO_LIST to give libraries access to all the errno values. --- ports/atmel-samd/mpconfigport.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 392b0773e..258b255ae 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -163,6 +163,18 @@ typedef long mp_off_t; #define MICROPY_PY_IO (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) #define MICROPY_PY_SYS_EXC_INFO (0) +#define MICROPY_PY_UERRNO_LIST \ + X(EPERM) \ + X(ENOENT) \ + X(EIO) \ + X(EAGAIN) \ + X(ENOMEM) \ + X(EACCES) \ + X(EEXIST) \ + X(ENODEV) \ + X(EISDIR) \ + X(EINVAL) \ + #endif #ifdef SAMD51 @@ -179,6 +191,7 @@ typedef long mp_off_t; #define MICROPY_PY_IO (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_EXC_INFO (1) +// MICROPY_PY_UERRNO_LIST - Use the default #endif #ifdef LONGINT_IMPL_NONE @@ -396,18 +409,6 @@ extern const struct _mp_obj_module_t wiznet_module; { MP_OBJ_NEW_QSTR(MP_QSTR_uheap),(mp_obj_t)&uheap_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_ustack),(mp_obj_t)&ustack_module } -#define MICROPY_PY_UERRNO_LIST \ - X(EPERM) \ - X(ENOENT) \ - X(EIO) \ - X(EAGAIN) \ - X(ENOMEM) \ - X(EACCES) \ - X(EEXIST) \ - X(ENODEV) \ - X(EISDIR) \ - X(EINVAL) \ - // We need to provide a declaration/definition of alloca() #include -- cgit v1.2.3 From a42515abbc897f5f9d27da53ff7afe6e47deb156 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 19:41:40 -0600 Subject: update /docs/drivers.rst page; 19 drivers added --- docs/drivers.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/drivers.rst b/docs/drivers.rst index 37bebb46a..4c5004d6b 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -66,6 +66,9 @@ These libraries build on top of the low level APIs to simplify common tasks. AVR programming DC Motor and Servo SD Card + miniQR Non-hardware QR code generator + Slideshow + LED Animation Blinky -------- @@ -111,6 +114,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and .. toctree:: + ADXL34x 3 Axis Accelerometer BNO055 Accelerometer, Magnetometer, Gyroscope and Absolution Orientation FXAS21002C Gyroscope FXOS8700 Accelerometer @@ -119,6 +123,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and LSM303 Accelerometer and Magnetometer LSM9DS0 Accelerometer, Magnetometer, Gyroscope and Temperature LSM9DS1 Accelerometer, Magnetometer, Gyroscope and Temperature + MLX90390 3 Axis Mangetometer MMA8451 3 axis accelerometer Environmental Sensors @@ -134,13 +139,18 @@ equivalent carbon dioxide (``eco2`` / ``eCO2``), and total volatile organic comp BME280 Temperature, Humidity and Pressure BME680 Temperature, Humidity, Pressure and Gas BMP280 Barometric Pressure and Altitude + BMP3xx Barometric Pressure and Altimeter CCS811 Air Quality DHT Temperature and Humidity DS18x20 Temperature + HTU21D Temperature and Humidity MAX31865 Thermocouple Amplifier, Temperature MAX31855 Thermocouple Amplifier, Temperature + MAX31856 Thermocouple Amplifier, Temperature MCP9808 Temperature + MP115A2 Barometric Pressure, Temperature MPL3115A2 Barometric Pressure, Altitude and Temperature Sensor + MPRLS Ported Absolute Pressure SGP30 Air Quality SHT31-D Temperature and Humidity Si7021 Temperature and Humidity @@ -161,6 +171,7 @@ These sensors detect light related attributes such as ``color``, ``light`` (unit TSL2591 High Dynamic Range Light Sensor VCNL4010 Proximity and Light VEML6070 UV Index + VEML6075 UV Index Distance Sensors ------------------ @@ -169,6 +180,8 @@ These sensors measure the ``distance`` to another object and may also measure li .. toctree:: + Garmin LIDARLite I2C + TFmini IR Time of Flight ~30cm - 12m VL6180x 5 - 100 mm VL53L0x ~30 - 1000 mm @@ -179,6 +192,7 @@ These chips communicate to other's over radio. .. toctree:: + Adafruit Bluefruit LE SPI Friend RFM9x LoRa RFM69 Packet Radio @@ -206,9 +220,12 @@ Miscellaneous .. toctree:: + CAP1188 8-Key Capacitive Touch Si4713 Stereo FM Transmitter AMG88xx Grid-Eye IR Camera Trellis 4x4 Keypad + NeoTrellis 4x4 Keypad + NeoTrellis M4 4x8 Keypad DRV2605 Haptic Motor Controller MAX9744 Audio Amplifier Si5351 Clock Generator @@ -216,3 +233,5 @@ Miscellaneous VC0706 TTL Camera INA219 High Side Current Fingerprint + VS1053 Audio Codec + FRAM Non-Volatile Memory -- cgit v1.2.3 From 028915d6f7cd5ea52452174a56729424d974f77b Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 19:45:11 -0600 Subject: update /docs/drivers.rst page; 19 drivers added --- docs/drivers.rst | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index 284bfc231..4c5004d6b 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -66,8 +66,9 @@ These libraries build on top of the low level APIs to simplify common tasks. AVR programming DC Motor and Servo SD Card - Image Load - LED Animation + miniQR Non-hardware QR code generator + Slideshow + LED Animation Blinky -------- @@ -79,7 +80,6 @@ Multi-color led drivers. NeoPixel DotStar WS2801 - Pixie Displays ------------- @@ -94,7 +94,6 @@ Drivers used to display information. Either pixel or segment based. IS31FL3731 Charlieplexed LED Matrix MAX7219 LED Matrix SSD1306 OLED Driver - E-Paper Display Real-time clocks ----------------- @@ -115,6 +114,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and .. toctree:: + ADXL34x 3 Axis Accelerometer BNO055 Accelerometer, Magnetometer, Gyroscope and Absolution Orientation FXAS21002C Gyroscope FXOS8700 Accelerometer @@ -123,8 +123,8 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and LSM303 Accelerometer and Magnetometer LSM9DS0 Accelerometer, Magnetometer, Gyroscope and Temperature LSM9DS1 Accelerometer, Magnetometer, Gyroscope and Temperature + MLX90390 3 Axis Mangetometer MMA8451 3 axis accelerometer - L3GD20 Gyroscope Environmental Sensors ---------------------- @@ -139,19 +139,22 @@ equivalent carbon dioxide (``eco2`` / ``eCO2``), and total volatile organic comp BME280 Temperature, Humidity and Pressure BME680 Temperature, Humidity, Pressure and Gas BMP280 Barometric Pressure and Altitude + BMP3xx Barometric Pressure and Altimeter CCS811 Air Quality DHT Temperature and Humidity DS18x20 Temperature + HTU21D Temperature and Humidity MAX31865 Thermocouple Amplifier, Temperature MAX31855 Thermocouple Amplifier, Temperature + MAX31856 Thermocouple Amplifier, Temperature MCP9808 Temperature + MP115A2 Barometric Pressure, Temperature MPL3115A2 Barometric Pressure, Altitude and Temperature Sensor + MPRLS Ported Absolute Pressure SGP30 Air Quality SHT31-D Temperature and Humidity Si7021 Temperature and Humidity Thermistor Temperature - TMP007 Contactless Temperature - MLX90614 Contactless Temperature Light Sensors --------------- @@ -168,6 +171,7 @@ These sensors detect light related attributes such as ``color``, ``light`` (unit TSL2591 High Dynamic Range Light Sensor VCNL4010 Proximity and Light VEML6070 UV Index + VEML6075 UV Index Distance Sensors ------------------ @@ -176,9 +180,10 @@ These sensors measure the ``distance`` to another object and may also measure li .. toctree:: + Garmin LIDARLite I2C + TFmini IR Time of Flight ~30cm - 12m VL6180x 5 - 100 mm VL53L0x ~30 - 1000 mm - HC-SR04 ultrasonic range sensors Radio -------- @@ -187,9 +192,9 @@ These chips communicate to other's over radio. .. toctree:: + Adafruit Bluefruit LE SPI Friend RFM9x LoRa RFM69 Packet Radio - PN532 NFC/RFID IO Expansion -------------- @@ -209,17 +214,18 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and ` TLC5947 24 x 12-bit PWM Driver TLC59711 12 x 16-bit PWM Driver MPR121 Capacitive Touch Sensor - TCA9548 I2C Multiplexer - MCP3xxx SPI ADC Miscellaneous ---------------- .. toctree:: + CAP1188 8-Key Capacitive Touch Si4713 Stereo FM Transmitter AMG88xx Grid-Eye IR Camera Trellis 4x4 Keypad + NeoTrellis 4x4 Keypad + NeoTrellis M4 4x8 Keypad DRV2605 Haptic Motor Controller MAX9744 Audio Amplifier Si5351 Clock Generator @@ -227,5 +233,5 @@ Miscellaneous VC0706 TTL Camera INA219 High Side Current Fingerprint - STMPE610 Resistive Touchscreen - Matrix Keypad + VS1053 Audio Codec + FRAM Non-Volatile Memory -- cgit v1.2.3 From b68517fbab09401c3ec3683c7513f317b6b356c3 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 23:24:53 -0600 Subject: replaced scrubbed drivers --- docs/drivers.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/drivers.rst b/docs/drivers.rst index 4c5004d6b..ab1858095 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -66,6 +66,7 @@ These libraries build on top of the low level APIs to simplify common tasks. AVR programming DC Motor and Servo SD Card + Image Load miniQR Non-hardware QR code generator Slideshow LED Animation @@ -80,6 +81,7 @@ Multi-color led drivers. NeoPixel DotStar WS2801 + Pixie Displays ------------- @@ -94,6 +96,7 @@ Drivers used to display information. Either pixel or segment based. IS31FL3731 Charlieplexed LED Matrix MAX7219 LED Matrix SSD1306 OLED Driver + E-Paper Display Real-time clocks ----------------- @@ -119,6 +122,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and FXAS21002C Gyroscope FXOS8700 Accelerometer GPS Global Position + L3GD20 Gyroscope LIS3DH Accelerometer LSM303 Accelerometer and Magnetometer LSM9DS0 Accelerometer, Magnetometer, Gyroscope and Temperature @@ -155,6 +159,8 @@ equivalent carbon dioxide (``eco2`` / ``eCO2``), and total volatile organic comp SHT31-D Temperature and Humidity Si7021 Temperature and Humidity Thermistor Temperature + TMP007 Contactless Temperature + MLX90614 Contactless Temperature Light Sensors --------------- @@ -184,6 +190,7 @@ These sensors measure the ``distance`` to another object and may also measure li TFmini IR Time of Flight ~30cm - 12m VL6180x 5 - 100 mm VL53L0x ~30 - 1000 mm + HC-SR04 Ultrasonic Range Sensors Radio -------- @@ -195,6 +202,7 @@ These chips communicate to other's over radio. Adafruit Bluefruit LE SPI Friend RFM9x LoRa RFM69 Packet Radio + PN532 NFC/RFID IO Expansion -------------- @@ -214,6 +222,8 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and ` TLC5947 24 x 12-bit PWM Driver TLC59711 12 x 16-bit PWM Driver MPR121 Capacitive Touch Sensor + TCA9548 I2C Multiplexer + MCP3xxx SPI ADC Miscellaneous ---------------- @@ -233,5 +243,7 @@ Miscellaneous VC0706 TTL Camera INA219 High Side Current Fingerprint + STMPE610 Resistive Touchscreen + Matrix Keypad VS1053 Audio Codec FRAM Non-Volatile Memory -- cgit v1.2.3 From a7a66e93992e45a59fd60a1db8e8b436aa3d0eb1 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 23:28:23 -0600 Subject: fix led-animation url; it has 2 valid urls... --- docs/drivers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index ab1858095..28325b850 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -69,7 +69,7 @@ These libraries build on top of the low level APIs to simplify common tasks. Image Load miniQR Non-hardware QR code generator Slideshow - LED Animation + LED Animation Blinky -------- -- cgit v1.2.3 From c669f7563cf42caf4cc6249215951198ef993a20 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 23:32:50 -0600 Subject: git diff review fail before push... --- docs/drivers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index 28325b850..199a51e4b 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -202,7 +202,7 @@ These chips communicate to other's over radio. Adafruit Bluefruit LE SPI Friend RFM9x LoRa RFM69 Packet Radio - PN532 NFC/RFID + PN532 NFC/RFID IO Expansion -------------- -- cgit v1.2.3 From e2bfe917005571963cd5c51e4d2ad7c4bbacb9c9 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Tue, 13 Nov 2018 23:37:27 -0600 Subject: i have no more words... --- docs/drivers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index 199a51e4b..ff67fcbfb 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -202,7 +202,7 @@ These chips communicate to other's over radio. Adafruit Bluefruit LE SPI Friend RFM9x LoRa RFM69 Packet Radio - PN532 NFC/RFID + PN532 NFC/RFID IO Expansion -------------- -- cgit v1.2.3 From fd3178b2fe1f6ccb7dc1519d795b973b7ff4214a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 14:54:00 -0800 Subject: Update TinyUSB with SAMD fixes. Fixes #1327 --- lib/tinyusb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tinyusb b/lib/tinyusb index 299a2f12d..c62d9a1fe 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 299a2f12de2ddb76b9a488b23e7e562058faee90 +Subproject commit c62d9a1fefa76bf59d43ff56ce6ca1e138a69c76 -- cgit v1.2.3 From 47212ee31e16c50e3c170514e1076a8651e22146 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 12 Nov 2018 13:59:29 -0800 Subject: start debug --- ports/nrf/Makefile | 4 ++-- supervisor/shared/filesystem.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8d0d6d000..b3d708725 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -78,8 +78,8 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_C #Debugging/Optimization ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ -CFLAGS += -O1 -ggdb -LDFLAGS += -O1 +CFLAGS += -Os -ggdb +LDFLAGS += -Os else CFLAGS += -Os -DNDEBUG LDFLAGS += -Os diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 264ba25f0..ebbc8c40d 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -50,7 +50,7 @@ void filesystem_init(bool create_allowed, bool force_create) { supervisor_flash_init_vfs(vfs_fat); // try to mount the flash - FRESULT res = f_mount(&vfs_fat->fatfs); + volatile FRESULT res = f_mount(&vfs_fat->fatfs); if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { // No filesystem so create a fresh one, or reformat has been requested. -- cgit v1.2.3 From 87ddd64481ea139bd0638baa03f106f7fcc0501e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 17:59:11 -0800 Subject: Factor out fake partition --- ports/atmel-samd/supervisor/internal_flash.c | 130 +++++++-------------------- ports/atmel-samd/supervisor/internal_flash.h | 1 - ports/nrf/supervisor/internal_flash.h | 2 - supervisor/shared/filesystem.c | 4 +- supervisor/shared/flash.c | 89 ++++++++++++++++-- 5 files changed, 120 insertions(+), 106 deletions(-) diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c index 6e097b214..f1ceb5c92 100644 --- a/ports/atmel-samd/supervisor/internal_flash.c +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -70,7 +70,7 @@ uint32_t supervisor_flash_get_block_size(void) { } uint32_t supervisor_flash_get_block_count(void) { - return INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS; + return INTERNAL_FLASH_PART1_NUM_BLOCKS; } void supervisor_flash_flush(void) { @@ -80,46 +80,9 @@ void flash_flush(void) { supervisor_flash_flush(); } -static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { - buf[0] = boot; - - if (num_blocks == 0) { - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - } else { - buf[1] = 0xff; - buf[2] = 0xff; - buf[3] = 0xff; - } - - buf[4] = type; - - if (num_blocks == 0) { - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - } else { - buf[5] = 0xff; - buf[6] = 0xff; - buf[7] = 0xff; - } - - buf[8] = start_block; - buf[9] = start_block >> 8; - buf[10] = start_block >> 16; - buf[11] = start_block >> 24; - - buf[12] = num_blocks; - buf[13] = num_blocks >> 8; - buf[14] = num_blocks >> 16; - buf[15] = num_blocks >> 24; -} - static int32_t convert_block_to_flash_addr(uint32_t block) { - if (INTERNAL_FLASH_PART1_START_BLOCK <= block && block < INTERNAL_FLASH_PART1_START_BLOCK + INTERNAL_FLASH_PART1_NUM_BLOCKS) { + if (0 <= block && block < INTERNAL_FLASH_PART1_NUM_BLOCKS) { // a block in partition 1 - block -= INTERNAL_FLASH_PART1_START_BLOCK; return INTERNAL_FLASH_MEM_SEG1_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; } // bad block @@ -127,69 +90,44 @@ static int32_t convert_block_to_flash_addr(uint32_t block) { } bool supervisor_flash_read_block(uint8_t *dest, uint32_t block) { - if (block == 0) { - // fake the MBR so we can decide on our own partition table - - for (int i = 0; i < 446; i++) { - dest[i] = 0; - } - - build_partition(dest + 446, 0, 0x01 /* FAT12 */, INTERNAL_FLASH_PART1_START_BLOCK, INTERNAL_FLASH_PART1_NUM_BLOCKS); - build_partition(dest + 462, 0, 0, 0, 0); - build_partition(dest + 478, 0, 0, 0, 0); - build_partition(dest + 494, 0, 0, 0, 0); - - dest[510] = 0x55; - dest[511] = 0xaa; - - return true; - - } else { - // non-MBR block, get data from flash memory - int32_t src = convert_block_to_flash_addr(block); - if (src == -1) { - // bad block number - return false; - } - int32_t error_code = flash_read(&supervisor_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE); - return error_code == ERR_NONE; + // non-MBR block, get data from flash memory + int32_t src = convert_block_to_flash_addr(block); + if (src == -1) { + // bad block number + return false; } + int32_t error_code = flash_read(&supervisor_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE); + return error_code == ERR_NONE; } bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { - if (block == 0) { - // can't write MBR, but pretend we did - return true; - - } else { - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, true); - #endif - temp_status_color(ACTIVE_WRITE); - // non-MBR block, copy to cache - int32_t dest = convert_block_to_flash_addr(block); - if (dest == -1) { - // bad block number - return false; - } - int32_t error_code; - error_code = flash_erase(&supervisor_flash_desc, - dest, - FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&supervisor_flash_desc)); - if (error_code != ERR_NONE) { - return false; - } + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + temp_status_color(ACTIVE_WRITE); + // non-MBR block, copy to cache + int32_t dest = convert_block_to_flash_addr(block); + if (dest == -1) { + // bad block number + return false; + } + int32_t error_code; + error_code = flash_erase(&supervisor_flash_desc, + dest, + FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&supervisor_flash_desc)); + if (error_code != ERR_NONE) { + return false; + } - error_code = flash_append(&supervisor_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE); - if (error_code != ERR_NONE) { - return false; - } - clear_temp_status(); - #ifdef MICROPY_HW_LED_MSC - port_pin_set_output_level(MICROPY_HW_LED_MSC, false); - #endif - return true; + error_code = flash_append(&supervisor_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE); + if (error_code != ERR_NONE) { + return false; } + clear_temp_status(); + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif + return true; } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h index b1074d93f..0939a3454 100644 --- a/ports/atmel-samd/supervisor/internal_flash.h +++ b/ports/atmel-samd/supervisor/internal_flash.h @@ -41,7 +41,6 @@ #endif #define INTERNAL_FLASH_MEM_SEG1_START_ADDR (FLASH_SIZE - TOTAL_INTERNAL_FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) -#define INTERNAL_FLASH_PART1_START_BLOCK (0x1) #define INTERNAL_FLASH_PART1_NUM_BLOCKS (TOTAL_INTERNAL_FLASH_SIZE / FILESYSTEM_BLOCK_SIZE) #define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms diff --git a/ports/nrf/supervisor/internal_flash.h b/ports/nrf/supervisor/internal_flash.h index adcb9bbc2..cf1dc91b5 100644 --- a/ports/nrf/supervisor/internal_flash.h +++ b/ports/nrf/supervisor/internal_flash.h @@ -31,8 +31,6 @@ #include "py/mpconfig.h" -#define FLASH_ROOT_POINTERS - #define FLASH_PAGE_SIZE 0x1000 #define CIRCUITPY_INTERNAL_NVM_SIZE 0 diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index ebbc8c40d..de9af5707 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -59,7 +59,7 @@ void filesystem_init(bool create_allowed, bool force_create) { // Flush the new file system to make sure it's repaired immediately. supervisor_flash_flush(); if (res != FR_OK) { - asm("bkpt"); + //asm("bkpt"); return; } @@ -75,7 +75,7 @@ void filesystem_init(bool create_allowed, bool force_create) { // and ensure everything is flushed supervisor_flash_flush(); } else if (res != FR_OK) { - asm("bkpt"); + //asm("bkpt"); return; } mp_vfs_mount_t *vfs = &_mp_vfs; diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c index 4fa2d8f75..c8921aa85 100644 --- a/supervisor/shared/flash.c +++ b/supervisor/shared/flash.c @@ -31,6 +31,8 @@ #define VFS_INDEX 0 +#define PART1_START_BLOCK (0x1) + void supervisor_flash_set_usb_writable(bool usb_writable) { mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); for (uint8_t i = 0; current_mount != NULL; i++) { @@ -63,10 +65,87 @@ STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t return (mp_obj_t)&supervisor_flash_obj; } +uint32_t flash_get_block_count(void) { + return PART1_START_BLOCK + supervisor_flash_get_block_count(); +} + +static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { + buf[0] = boot; + + if (num_blocks == 0) { + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + } else { + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + } + + buf[4] = type; + + if (num_blocks == 0) { + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + } else { + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xff; + } + + buf[8] = start_block; + buf[9] = start_block >> 8; + buf[10] = start_block >> 16; + buf[11] = start_block >> 24; + + buf[12] = num_blocks; + buf[13] = num_blocks >> 8; + buf[14] = num_blocks >> 16; + buf[15] = num_blocks >> 24; +} + +mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + if (block_num == 0) { + if (block_num > 1) { + return 1; // error + } + // fake the MBR so we can decide on our own partition table + + for (int i = 0; i < 446; i++) { + dest[i] = 0; + } + + build_partition(dest + 446, 0, 0x01 /* FAT12 */, PART1_START_BLOCK, supervisor_flash_get_block_count()); + build_partition(dest + 462, 0, 0, 0, 0); + build_partition(dest + 478, 0, 0, 0, 0); + build_partition(dest + 494, 0, 0, 0, 0); + + dest[510] = 0x55; + dest[511] = 0xaa; + + return 0; // ok + + } + return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks); +} + +mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + if (block_num == 0) { + if (num_blocks > 1) { + return 1; // error + } + // can't write MBR, but pretend we did + return 0; + } else { + return supervisor_flash_write_blocks(src, block_num - PART1_START_BLOCK, num_blocks); + } +} + STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); - mp_uint_t ret = supervisor_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + mp_uint_t ret = flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); return MP_OBJ_NEW_SMALL_INT(ret); } STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks); @@ -74,7 +153,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - mp_uint_t ret = supervisor_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + mp_uint_t ret = flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); return MP_OBJ_NEW_SMALL_INT(ret); } STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks); @@ -85,7 +164,7 @@ STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_ob case BP_IOCTL_INIT: supervisor_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); case BP_IOCTL_DEINIT: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly case BP_IOCTL_SYNC: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); - case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_count()); + case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(flash_get_block_count()); case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_size()); default: return mp_const_none; } @@ -114,10 +193,10 @@ void supervisor_flash_init_vfs(fs_user_mount_t *vfs) { vfs->fatfs.part = 1; // flash filesystem lives on first partition vfs->readblocks[0] = (mp_obj_t)&supervisor_flash_obj_readblocks_obj; vfs->readblocks[1] = (mp_obj_t)&supervisor_flash_obj; - vfs->readblocks[2] = (mp_obj_t)supervisor_flash_read_blocks; // native version + vfs->readblocks[2] = (mp_obj_t)flash_read_blocks; // native version vfs->writeblocks[0] = (mp_obj_t)&supervisor_flash_obj_writeblocks_obj; vfs->writeblocks[1] = (mp_obj_t)&supervisor_flash_obj; - vfs->writeblocks[2] = (mp_obj_t)supervisor_flash_write_blocks; // native version + vfs->writeblocks[2] = (mp_obj_t)flash_write_blocks; // native version vfs->u.ioctl[0] = (mp_obj_t)&supervisor_flash_obj_ioctl_obj; vfs->u.ioctl[1] = (mp_obj_t)&supervisor_flash_obj; } -- cgit v1.2.3 From b67c53edfaa5792b8cfb38976a9853a1224acc50 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 18:30:47 -0800 Subject: Factor out of external flash as well. Plus some cleanup. Fixes #1324 --- ports/nrf/Makefile | 4 +- supervisor/shared/external_flash/external_flash.c | 195 +++++++--------------- supervisor/shared/filesystem.c | 4 +- 3 files changed, 66 insertions(+), 137 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index b3d708725..8d0d6d000 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -78,8 +78,8 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_C #Debugging/Optimization ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ -CFLAGS += -Os -ggdb -LDFLAGS += -Os +CFLAGS += -O1 -ggdb +LDFLAGS += -O1 else CFLAGS += -Os -DNDEBUG LDFLAGS += -Os diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c index defdfa393..73b7f7f91 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -40,8 +40,6 @@ #include "supervisor/memory.h" #include "supervisor/shared/rgb_led_status.h" -#define SPI_FLASH_PART1_START_BLOCK (0x1) - #define NO_SECTOR_LOADED 0xFFFFFFFF // The currently cached sector in the cache, ram or flash based. @@ -268,7 +266,7 @@ uint32_t supervisor_flash_get_block_size(void) { uint32_t supervisor_flash_get_block_count(void) { // We subtract one erase sector size because we may use it as a staging area // for writes. - return SPI_FLASH_PART1_START_BLOCK + (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; + return (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; } // Flush the cache that was written to the scratch portion of flash. Only used @@ -444,48 +442,9 @@ void supervisor_flash_flush(void) { spi_flash_flush_keep_cache(false); } -// Builds a partition entry for the MBR. -static void build_partition(uint8_t *buf, int boot, int type, - uint32_t start_block, uint32_t num_blocks) { - buf[0] = boot; - - if (num_blocks == 0) { - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - } else { - buf[1] = 0xff; - buf[2] = 0xff; - buf[3] = 0xff; - } - - buf[4] = type; - - if (num_blocks == 0) { - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - } else { - buf[5] = 0xff; - buf[6] = 0xff; - buf[7] = 0xff; - } - - buf[8] = start_block; - buf[9] = start_block >> 8; - buf[10] = start_block >> 16; - buf[11] = start_block >> 24; - - buf[12] = num_blocks; - buf[13] = num_blocks >> 8; - buf[14] = num_blocks >> 16; - buf[15] = num_blocks >> 24; -} - static int32_t convert_block_to_flash_addr(uint32_t block) { - if (SPI_FLASH_PART1_START_BLOCK <= block && block < supervisor_flash_get_block_count()) { + if (0 <= block && block < supervisor_flash_get_block_count()) { // a block in partition 1 - block -= SPI_FLASH_PART1_START_BLOCK; return block * FILESYSTEM_BLOCK_SIZE; } // bad block @@ -493,106 +452,78 @@ static int32_t convert_block_to_flash_addr(uint32_t block) { } bool external_flash_read_block(uint8_t *dest, uint32_t block) { - if (block == 0) { - // Fake the MBR so we can decide on our own partition table - for (int i = 0; i < 446; i++) { - dest[i] = 0; - } - - build_partition(dest + 446, 0, 0x01 /* FAT12 */, - SPI_FLASH_PART1_START_BLOCK, - supervisor_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK); - build_partition(dest + 462, 0, 0, 0, 0); - build_partition(dest + 478, 0, 0, 0, 0); - build_partition(dest + 494, 0, 0, 0, 0); - - dest[510] = 0x55; - dest[511] = 0xaa; - - return true; - } else if (block < SPI_FLASH_PART1_START_BLOCK) { - memset(dest, 0, FILESYSTEM_BLOCK_SIZE); - return true; - } else { - // Non-MBR block, get data from flash memory. - int32_t address = convert_block_to_flash_addr(block); - if (address == -1) { - // bad block number - return false; - } - - // Mask out the lower bits that designate the address within the sector. - uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); - uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); - uint8_t mask = 1 << (block_index); - // We're reading from the currently cached sector. - if (current_sector == this_sector && (mask & dirty_mask) > 0) { - if (MP_STATE_VM(flash_ram_cache) != NULL) { - uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; - for (int i = 0; i < pages_per_block; i++) { - memcpy(dest + i * SPI_FLASH_PAGE_SIZE, - MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], - SPI_FLASH_PAGE_SIZE); - } - return true; - } else { - uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; - return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE); - } - } - return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; } -} -bool external_flash_write_block(const uint8_t *data, uint32_t block) { - if (block < SPI_FLASH_PART1_START_BLOCK) { - // Fake writing below the flash partition. - return true; - } else { - // Non-MBR block, copy to cache - int32_t address = convert_block_to_flash_addr(block); - if (address == -1) { - // bad block number - return false; - } - // Wait for any previous writes to finish. - wait_for_flash_ready(); - // Mask out the lower bits that designate the address within the sector. - uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); - uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); - uint8_t mask = 1 << (block_index); - // Flush the cache if we're moving onto a sector or we're writing the - // same block again. - if (current_sector != this_sector || (mask & dirty_mask) > 0) { - // Check to see if we'd write to an erased page. In that case we - // can write directly. - if (page_erased(address)) { - return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); - } - if (current_sector != NO_SECTOR_LOADED) { - spi_flash_flush_keep_cache(true); - } - if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) { - erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE); - wait_for_flash_ready(); - } - current_sector = this_sector; - dirty_mask = 0; - } - dirty_mask |= mask; - // Copy the block to the appropriate cache. + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // We're reading from the currently cached sector. + if (current_sector == this_sector && (mask & dirty_mask) > 0) { if (MP_STATE_VM(flash_ram_cache) != NULL) { uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; for (int i = 0; i < pages_per_block; i++) { - memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], - data + i * SPI_FLASH_PAGE_SIZE, + memcpy(dest + i * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], SPI_FLASH_PAGE_SIZE); } return true; } else { uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; - return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE); + return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE); + } + } + return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); +} + +bool external_flash_write_block(const uint8_t *data, uint32_t block) { + // Non-MBR block, copy to cache + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + // Wait for any previous writes to finish. + wait_for_flash_ready(); + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // Flush the cache if we're moving onto a sector or we're writing the + // same block again. + if (current_sector != this_sector || (mask & dirty_mask) > 0) { + // Check to see if we'd write to an erased page. In that case we + // can write directly. + if (page_erased(address)) { + return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); + } + if (current_sector != NO_SECTOR_LOADED) { + spi_flash_flush_keep_cache(true); + } + if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) { + erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE); + wait_for_flash_ready(); } + current_sector = this_sector; + dirty_mask = 0; + } + dirty_mask |= mask; + // Copy the block to the appropriate cache. + if (MP_STATE_VM(flash_ram_cache) != NULL) { + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (int i = 0; i < pages_per_block; i++) { + memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], + data + i * SPI_FLASH_PAGE_SIZE, + SPI_FLASH_PAGE_SIZE); + } + return true; + } else { + uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; + return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE); } } diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index de9af5707..d968f4798 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -50,7 +50,7 @@ void filesystem_init(bool create_allowed, bool force_create) { supervisor_flash_init_vfs(vfs_fat); // try to mount the flash - volatile FRESULT res = f_mount(&vfs_fat->fatfs); + FRESULT res = f_mount(&vfs_fat->fatfs); if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { // No filesystem so create a fresh one, or reformat has been requested. @@ -59,7 +59,6 @@ void filesystem_init(bool create_allowed, bool force_create) { // Flush the new file system to make sure it's repaired immediately. supervisor_flash_flush(); if (res != FR_OK) { - //asm("bkpt"); return; } @@ -75,7 +74,6 @@ void filesystem_init(bool create_allowed, bool force_create) { // and ensure everything is flushed supervisor_flash_flush(); } else if (res != FR_OK) { - //asm("bkpt"); return; } mp_vfs_mount_t *vfs = &_mp_vfs; -- cgit v1.2.3 From df663e42e939b50ad61cf192dc708e1495882887 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 14 Nov 2018 22:02:19 -0600 Subject: remove pca10056 from 3.x travis builds --- tools/build_adafruit_bins.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 29ee35c6a..961162bd3 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -2,7 +2,7 @@ rm -rf ports/atmel-samd/build* rm -rf ports/esp8266/build* rm -rf ports/nrf/build* -ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m0_express_crickit feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52832 feather_huzzah pca10056 hallowing_m0_express" +ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m0_express_crickit feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52832 feather_huzzah hallowing_m0_express" ROSIE_SETUPS="rosie-ci" PARALLEL="-j 5" -- cgit v1.2.3 From 3f9b0f764d7977aa891bae8fd49ddbc31a81f50a Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 14 Nov 2018 22:18:32 -0600 Subject: remove pca10056 from 3.x .travis.yml too --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f123fe6e..330a16e41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ env: - TRAVIS_BOARD=gemma_m0 - TRAVIS_BOARD=hallowing_m0_express - TRAVIS_BOARD=feather52832 - - TRAVIS_BOARD=pca10056 +# - TRAVIS_BOARD=pca10056 - TRAVIS_TEST=qemu - TRAVIS_TEST=unix - TRAVIS_TEST=docs -- cgit v1.2.3 From 55a9e2d6971b57cac0978f76b6116577f55ea914 Mon Sep 17 00:00:00 2001 From: Carlos Date: Sun, 18 Nov 2018 10:41:35 -0600 Subject: Fix time.monotonic_ns docstring --- shared-bindings/time/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 8a5e16c5e..5cd3a94cd 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -206,7 +206,7 @@ STATIC mp_obj_t time_time(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); -//| .. method:: monotonic_ns(clk_id) +//| .. method:: monotonic_ns() //| //| Return the time of the specified clock clk_id in nanoseconds. Refer to //| Clock ID Constants for a list of accepted values for clk_id. -- cgit v1.2.3 From 060b84a0fae485e8b0cbd32e8fc4ada2211e78f2 Mon Sep 17 00:00:00 2001 From: Carlos Date: Sun, 18 Nov 2018 10:43:28 -0600 Subject: Remove reference to clock_id on the function descriptiions --- shared-bindings/time/__init__.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 5cd3a94cd..f97ad4a5d 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -208,8 +208,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); //| .. method:: monotonic_ns() //| -//| Return the time of the specified clock clk_id in nanoseconds. Refer to -//| Clock ID Constants for a list of accepted values for clk_id. +//| Return the time of the specified clock clk_id in nanoseconds. //| //| :return: the current time //| :rtype: int -- cgit v1.2.3 From d7aa790e4b6aa8a2d6ae8b49b308728ff3942003 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 21 Nov 2018 12:55:01 -0600 Subject: add trailing '/' to links missing them --- docs/drivers.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index ff67fcbfb..e2d1e467d 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -147,14 +147,14 @@ equivalent carbon dioxide (``eco2`` / ``eCO2``), and total volatile organic comp CCS811 Air Quality DHT Temperature and Humidity DS18x20 Temperature - HTU21D Temperature and Humidity + HTU21D Temperature and Humidity MAX31865 Thermocouple Amplifier, Temperature MAX31855 Thermocouple Amplifier, Temperature MAX31856 Thermocouple Amplifier, Temperature MCP9808 Temperature MP115A2 Barometric Pressure, Temperature MPL3115A2 Barometric Pressure, Altitude and Temperature Sensor - MPRLS Ported Absolute Pressure + MPRLS Ported Absolute Pressure SGP30 Air Quality SHT31-D Temperature and Humidity Si7021 Temperature and Humidity @@ -186,8 +186,8 @@ These sensors measure the ``distance`` to another object and may also measure li .. toctree:: - Garmin LIDARLite I2C - TFmini IR Time of Flight ~30cm - 12m + Garmin LIDARLite I2C + TFmini IR Time of Flight ~30cm - 12m VL6180x 5 - 100 mm VL53L0x ~30 - 1000 mm HC-SR04 Ultrasonic Range Sensors @@ -234,7 +234,7 @@ Miscellaneous Si4713 Stereo FM Transmitter AMG88xx Grid-Eye IR Camera Trellis 4x4 Keypad - NeoTrellis 4x4 Keypad + NeoTrellis 4x4 Keypad NeoTrellis M4 4x8 Keypad DRV2605 Haptic Motor Controller MAX9744 Audio Amplifier -- cgit v1.2.3 From 59430ea26dd8b140dd5792e298fed2e1bcae7eb1 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 21 Nov 2018 12:58:11 -0600 Subject: fix L3GD20 link --- docs/drivers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index e2d1e467d..d3573a547 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -122,7 +122,7 @@ Motion relating sensing including ``acceleration``, ``magnetic``, ``gyro``, and FXAS21002C Gyroscope FXOS8700 Accelerometer GPS Global Position - L3GD20 Gyroscope + L3GD20 Gyroscope LIS3DH Accelerometer LSM303 Accelerometer and Magnetometer LSM9DS0 Accelerometer, Magnetometer, Gyroscope and Temperature -- cgit v1.2.3 From 4254ae6d5b278bb4f54f70731067eb3bbccb36cb Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 21 Nov 2018 13:05:02 -0600 Subject: add 74HC595 --- docs/drivers.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/drivers.rst b/docs/drivers.rst index d3573a547..119706d33 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -247,3 +247,4 @@ Miscellaneous Matrix Keypad VS1053 Audio Codec FRAM Non-Volatile Memory + 74HC595 Shift Register -- cgit v1.2.3 From 5fe746f64352d3b6d3bec651d655ae302a971863 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 21 Nov 2018 19:46:49 -0500 Subject: Latest Feather nRF52840 pin revisions --- .../feather_nrf52840_express/mpconfigboard.h | 28 +++++------ .../feather_nrf52840_express/mpconfigboard.mk | 2 +- ports/nrf/boards/feather_nrf52840_express/pins.c | 56 ++++++++++++---------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index 68914c626..c52b69cf4 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -33,14 +33,14 @@ #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_PY_SYS_PLATFORM "Feather52840Express" -#define MICROPY_HW_NEOPIXEL (&pin_P0_13) +#define MICROPY_HW_NEOPIXEL (&pin_P0_16) -#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 9) -#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 11) -#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 12) -#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 14) -#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 8) -#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8) +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 @@ -55,12 +55,12 @@ #define BOARD_HAS_CRYSTAL 1 -#define DEFAULT_I2C_BUS_SCL (&pin_P1_11) -#define DEFAULT_I2C_BUS_SDA (&pin_P1_12) +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_12) -#define DEFAULT_SPI_BUS_SCK (&pin_P0_20) -#define DEFAULT_SPI_BUS_MOSI (&pin_P0_23) -#define DEFAULT_SPI_BUS_MISO (&pin_P0_22) +#define DEFAULT_SPI_BUS_SCK (&pin_P0_14) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_15) -#define DEFAULT_UART_BUS_RX (&pin_P1_00) -#define DEFAULT_UART_BUS_TX (&pin_P0_24) +#define DEFAULT_UART_BUS_RX (&pin_P0_24) +#define DEFAULT_UART_BUS_TX (&pin_P0_25) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk index f03109319..905921a5d 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk @@ -22,4 +22,4 @@ NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 -EXTERNAL_FLASH_DEVICES = "GD25Q64C" +EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 0f5eab31d..b85b72af0 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -3,39 +3,47 @@ #include "board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_13) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_14) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_20) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_23) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_TXD), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_RXD), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_TXD), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_RXD), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P1_11) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P1_02) }, - { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); -- cgit v1.2.3 From 78972cc879fd3ea82e56c23a8f94e81adb6ec719 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 22 Nov 2018 09:27:23 -0600 Subject: ports/atmel-samd: enable json module on M4 boards with lots of flash --- ports/atmel-samd/mpconfigport.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 392b0773e..829a0faaf 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -286,6 +286,14 @@ extern const struct _mp_obj_module_t wiznet_module; #define WIZNET_MODULE #endif + // (u)json depends, perhaps erroneously, on MICROPY_PY_IO + #if MICROPY_PY_IO + #define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, + #define MICROPY_PY_UJSON (1) + #else + #define JSON_MODULE + #endif + #ifndef EXTRA_BUILTIN_MODULES #define EXTRA_BUILTIN_MODULES \ @@ -297,6 +305,7 @@ extern const struct _mp_obj_module_t wiznet_module; NETWORK_MODULE \ SOCKET_MODULE \ WIZNET_MODULE \ + JSON_MODULE \ { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module } #endif -- cgit v1.2.3 From 52fd151c9c824ee9c51a401019e44c2e4695fbeb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 22 Nov 2018 09:28:13 -0600 Subject: ports/nrf: enable json module on nrf boards generally --- ports/nrf/mpconfigport.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 7b2b8f1d1..86f5af20a 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -112,7 +112,7 @@ #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) #define MICROPY_PY_UCTYPES (0) #define MICROPY_PY_UZLIB (0) -#define MICROPY_PY_UJSON (0) +#define MICROPY_PY_UJSON (1) #define MICROPY_PY_URE (0) #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UHASHLIB (1) @@ -204,6 +204,7 @@ extern const struct _mp_obj_module_t bleio_module; { MP_OBJ_NEW_QSTR (MP_QSTR_supervisor ), (mp_obj_t)&supervisor_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ + { MP_OBJ_NEW_QSTR (MP_QSTR_json ), (mp_obj_t)&mp_module_ujson }, \ USBHID_MODULE \ BLEIO_MODULE -- cgit v1.2.3 From 324301e3bc23d3c5d2b7aebff745999c38532d19 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 23 Nov 2018 12:51:11 -0800 Subject: Update tinyusb to include control fixes. --- lib/tinyusb | 2 +- ports/atmel-samd/Makefile | 6 ++---- ports/nrf/Makefile | 9 +-------- supervisor/shared/usb/usb_msc_flash.c | 15 ++++----------- supervisor/supervisor.mk | 2 +- 5 files changed, 9 insertions(+), 25 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index c62d9a1fe..47fabe42e 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit c62d9a1fefa76bf59d43ff56ce6ca1e138a69c76 +Subproject commit 47fabe42edaae4a5da6aa0d48c664a9184578753 diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 23fb39779..99b8842c6 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -61,7 +61,6 @@ BASE_CFLAGS = \ -Wno-endif-labels \ -Wstrict-prototypes \ -Werror-implicit-function-declaration \ - -Wpointer-arith \ -Wfloat-equal \ -Wundef \ -Wshadow \ @@ -69,7 +68,6 @@ BASE_CFLAGS = \ -Wsign-compare \ -Wmissing-format-attribute \ -Wno-deprecated-declarations \ - -Wpacked \ -Wnested-externs \ -Wunreachable-code \ -Wcast-align \ @@ -265,8 +263,8 @@ SRC_C = \ lib/oofatfs/ff.c \ lib/oofatfs/option/ccsbcs.c \ lib/timeutils/timeutils.c \ - lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd.c \ - lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal.c \ + lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \ + lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c \ lib/utils/buffer_helper.c \ lib/utils/context_manager_helpers.c \ lib/utils/interrupt_char.c \ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8d0d6d000..558731a44 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -218,14 +218,7 @@ ifeq ($(MCU_SUB_VARIANT),nrf52840) SRC_C += \ lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c \ - lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c \ - lib/tinyusb/src/common/tusb_fifo.c \ - lib/tinyusb/src/device/control.c \ - lib/tinyusb/src/device/usbd.c \ - lib/tinyusb/src/class/msc/msc_device.c \ - lib/tinyusb/src/class/cdc/cdc_device.c \ - lib/tinyusb/src/class/hid/hid_device.c \ - lib/tinyusb/src/tusb.c \ + lib/tinyusb/src/portable/nordic/nrf5x/hal_nrf5x.c SRC_SHARED_MODULE += \ usb_hid/__init__.c \ diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 13b5c3966..658aab0d8 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -133,17 +133,10 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, return resplen; } -bool tud_lun_capacity_cb(uint8_t lun, uint32_t* last_valid_sector, uint16_t* sector_size) { - fs_user_mount_t * vfs = get_vfs(lun); - if (vfs == NULL || - disk_ioctl(vfs, GET_SECTOR_COUNT, last_valid_sector) != RES_OK || - disk_ioctl(vfs, GET_SECTOR_SIZE, sector_size) != RES_OK) { - return false; - } - // Subtract one from the sector count to get the last valid sector. - (*last_valid_sector)--; - - return true; +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { + fs_user_mount_t * vfs = get_vfs(lun); + disk_ioctl(vfs, GET_SECTOR_COUNT, block_count); + disk_ioctl(vfs, GET_SECTOR_SIZE, block_size); } bool tud_msc_is_writable_cb(uint8_t lun) { diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index ac982d277..73c76ebb7 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -43,8 +43,8 @@ ifeq ($(USB),FALSE) endif else SRC_SUPERVISOR += lib/tinyusb/src/common/tusb_fifo.c \ - lib/tinyusb/src/device/control.c \ lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/device/usbd_control.c \ lib/tinyusb/src/class/msc/msc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/hid/hid_device.c \ -- cgit v1.2.3 From 15eeac5d4bc796f09b70ad7b3b52f8fc2175a344 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 23 Nov 2018 14:22:07 -0800 Subject: A few fixes for nRF52840 feather QSPI and neopixel --- .../nrf/boards/feather_nrf52840_express/mpconfigboard.h | 11 +++++++++-- .../nrf/boards/feather_nrf52840_express/mpconfigboard.mk | 2 +- ports/nrf/common-hal/microcontroller/Pin.c | 2 -- ports/nrf/common-hal/neopixel_write/__init__.c | 16 ++++++++++++++-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index c52b69cf4..bd1cad504 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -35,12 +35,21 @@ #define MICROPY_HW_NEOPIXEL (&pin_P0_16) +#ifdef QSPI_FLASH_FILESYSTEM #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) #define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) #define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) #define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) #define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) #define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) +#endif + +#ifdef SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_17 +#define SPI_FLASH_MISO_PIN &pin_P0_22 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_20 +#endif #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 @@ -51,8 +60,6 @@ #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#define EXTERNAL_FLASH_QSPI_DUAL (1) - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_P0_11) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk index 905921a5d..bc511e150 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk @@ -20,6 +20,6 @@ endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 -QSPI_FLASH_FILESYSTEM = 1 +SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index 0522bfef3..02847e150 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -48,7 +48,6 @@ STATIC uint32_t claimed_pins[GPIO_COUNT]; STATIC uint32_t never_reset_pins[GPIO_COUNT]; void reset_all_pins(void) { - return; for (size_t i = 0; i < GPIO_COUNT; i++) { claimed_pins[i] = never_reset_pins[i]; } @@ -77,7 +76,6 @@ void reset_all_pins(void) { // Mark pin as free and return it to a quiescent state. void reset_pin_number(uint8_t pin_number) { - return; if (pin_number == NO_PIN) { return; } diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c index ef5e8beb1..c4cb194f3 100644 --- a/ports/nrf/common-hal/neopixel_write/__init__.c +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -108,12 +108,21 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout // using DWT uint32_t pattern_size = numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t); uint16_t* pixels_pattern = NULL; + bool pattern_on_heap = false; + + // Use the stack to store 1 pixels worth of PWM data for the status led. uint32_t to ensure alignment. + uint32_t one_pixel[8 * sizeof(uint16_t) + 1]; NRF_PWM_Type* pwm = find_free_pwm(); // only malloc if there is PWM device available if ( pwm != NULL ) { - pixels_pattern = (uint16_t *) m_malloc(pattern_size, false); + if (numBytes == 4) { + pixels_pattern = (uint16_t *) one_pixel; + } else { + pixels_pattern = (uint16_t *) m_malloc_maybe(pattern_size, false); + pattern_on_heap = true; + } } // Use the identified device to choose the implementation @@ -193,7 +202,10 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout nrf_pwm_disable(pwm); nrf_pwm_pins_set(pwm, (uint32_t[]) {0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL} ); - m_free(pixels_pattern); + if (pattern_on_heap) { + m_free(pixels_pattern); + } + } // End of DMA implementation // --------------------------------------------------------------------- else { -- cgit v1.2.3 From 0c55ddf0fca8760c9e167f6ee9f069ae1e15801b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 26 Nov 2018 10:16:55 -0800 Subject: Update to Xenial on Travis --- .travis.yml | 14 +++++++------- tools/build_adafruit_bins.sh | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 77642872e..737a031a6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: required -dist: trusty +dist: xenial language: c compiler: - gcc @@ -47,7 +47,7 @@ before_script: - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - sudo dpkg --add-architecture i386 - - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) + - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~xenial1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) # For nrf builds - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/bluetooth/download_ble_stack.sh) @@ -64,7 +64,7 @@ before_script: # report some good version numbers to the build - gcc --version - - (! var_search "${TRAVIS_SDK-}" elf || arm-none-eabi-gcc --version) + - (! var_search "${TRAVIS_SDK-}" arm || arm-none-eabi-gcc --version) - (! var_search "${TRAVIS_SDK-}" esp8266 || xtensa-lx106-elf-gcc --version) - python3 --version @@ -88,19 +88,19 @@ script: # run tests with coverage info - echo 'Test all' && echo -en 'travis_fold:start:test_all\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1)) - echo -en 'travis_fold:end:test_all\\r' - echo 'Test threads' && echo -en 'travis_fold:start:test_threads\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread)) - echo -en 'travis_fold:end:test_threads\\r' - echo 'Testing with native' && echo -en 'travis_fold:start:test_native\\r' - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native)) - echo -en 'travis_fold:end:test_native\\r' - (echo 'Testing with mpy' && echo -en 'travis_fold:start:test_mpy\\r') - - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) + - (! var_search "${TRAVIS_TESTS-}" unix || (cd tests && MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float)) - echo -en 'travis_fold:end:test_mpy\\r' - (echo 'Building docs' && echo -en 'travis_fold:start:build_docs\\r') diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 840e6f24e..20744ab75 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -69,8 +69,9 @@ for board in $boards; do for language_file in $(ls locale/*.po); do language=$(basename -s .po $language_file) echo "Building $board for $language" + # There is a bug in the Huzzah Makefile that causes it to fail occasionally with -j > 1. if [[ $board == "feather_huzzah" ]]; then - make $PARALLEL -C ports/esp8266 TRANSLATION=$language BOARD=$board + make -C ports/esp8266 TRANSLATION=$language BOARD=$board (( exit_status = exit_status || $? )) temp_filename=ports/esp8266/build/firmware-combined.bin extension=bin -- cgit v1.2.3 From 1da2425612f5cef5c7a8928fb029e2697e2c0340 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Mon, 26 Nov 2018 14:39:58 -0600 Subject: Add Electronic Cats CatWAN USB Stick --- ports/atmel-samd/boards/catwan_usbstick/board.c | 38 ++++++++++++++ .../boards/catwan_usbstick/mpconfigboard.h | 58 ++++++++++++++++++++++ .../boards/catwan_usbstick/mpconfigboard.mk | 11 ++++ ports/atmel-samd/boards/catwan_usbstick/pins.c | 19 +++++++ 4 files changed, 126 insertions(+) create mode 100644 ports/atmel-samd/boards/catwan_usbstick/board.c create mode 100644 ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/catwan_usbstick/pins.c diff --git a/ports/atmel-samd/boards/catwan_usbstick/board.c b/ports/atmel-samd/boards/catwan_usbstick/board.c new file mode 100644 index 000000000..c8e20206a --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h new file mode 100644 index 000000000..341dcc27e --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h @@ -0,0 +1,58 @@ +#define MICROPY_HW_BOARD_NAME "Electronic Cats CatWAN USBStick" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_RX &pin_PA14 + +#define MICROPY_PORT_A (PORT_PA14) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define DEFAULT_SPI_BUS_SCK (&pin_PA19) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA18) +#define DEFAULT_SPI_BUS_MISO (&pin_PA22) + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA07 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk new file mode 100644 index 000000000..fd4590166 --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0xBAB2 +USB_PID = 0x1209 +USB_PRODUCT = "CatWAN USBStick" +USB_MANUFACTURER = "Electronic Cats" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/catwan_usbstick/pins.c b/ports/atmel-samd/boards/catwan_usbstick/pins.c new file mode 100644 index 000000000..8997b653f --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/pins.c @@ -0,0 +1,19 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D0), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D2), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_RST), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_CS), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); -- cgit v1.2.3 From a053eb2205d6652ec1dec6ff25f02acd81c8c437 Mon Sep 17 00:00:00 2001 From: sabas1080 Date: Mon, 26 Nov 2018 14:51:04 -0600 Subject: auto-built and documentation --- .travis.yml | 2 +- README.rst | 1 + tools/build_adafruit_bins.sh | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 77642872e..12a7a632c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: - TRAVIS_BOARDS="metro_m0_express metro_m4_express pirkey_m0 trellis_m4_express trinket_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300" TRAVIS_SDK=arm - - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express" TRAVIS_SDK=arm + - TRAVIS_BOARDS="circuitplayground_express_crickit feather_m0_adalogger feather_m0_basic feather_m0_express catwan_usbstick" TRAVIS_SDK=arm addons: artifacts: diff --git a/README.rst b/README.rst index bf21204fb..138dbfea7 100644 --- a/README.rst +++ b/README.rst @@ -65,6 +65,7 @@ Other ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - `Electronic Cats Meow Meow `__ +- `Electronic Cats CatWAN USB Stick `__ Download diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 840e6f24e..553e0ea1e 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -8,6 +8,7 @@ rm -rf ports/nrf/build* HW_BOARDS="\ arduino_mkr1300 \ arduino_zero \ +catwan_usbstick \ circuitplayground_express \ circuitplayground_express_crickit \ feather_huzzah \ -- cgit v1.2.3 From d446d328d83fa38f095a0c19d3f22c35a581dcdf Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 26 Nov 2018 16:00:27 -0800 Subject: Fix QSPI on Feather nRF52840 We were writing with quad page program including the address (0x38) which is unsupported by the GD25Q16C but it is supported by the flash on the DK. So, we use the single address, quad data command (0x32). --- .../boards/feather_nrf52840_express/mpconfigboard.mk | 2 +- ports/nrf/supervisor/qspi_flash.c | 18 +++++++++++++++--- supervisor/shared/external_flash/devices.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk index bc511e150..905921a5d 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk @@ -20,6 +20,6 @@ endif NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 -SPI_FLASH_FILESYSTEM = 1 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 24b06c420..048db06f2 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -115,7 +115,7 @@ void spi_flash_init(void) { .dpmconfig = false }, .phy_if = { - .sck_freq = NRF_QSPI_FREQ_32MDIV16, + .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2mhz and speed up once we know what we're talking to. .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns .spi_mode = NRF_QSPI_MODE_0, .dpmen = false @@ -132,7 +132,7 @@ void spi_flash_init(void) { qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2; qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3; qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO; - qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO; + qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O; #endif // No callback for blocking API @@ -142,5 +142,17 @@ void spi_flash_init(void) { void spi_flash_init_device(const external_flash_device* device) { check_quad_enable(device); - // TODO(tannewt): Adjust the speed for the found device. + // Switch to single output line if the device doesn't support quad programs. + if (!device->supports_qspi_writes) { + NRF_QSPI->IFCONFIG0 &= ~QSPI_IFCONFIG0_WRITEOC_Msk; + NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP; + } + + // Speed up as much as we can. + uint8_t sckfreq = 0; + while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) { + sckfreq += 1; + } + NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; + NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKDELAY_Pos; } diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h index 06fc178cb..86e0868d0 100644 --- a/supervisor/shared/external_flash/devices.h +++ b/supervisor/shared/external_flash/devices.h @@ -86,7 +86,7 @@ typedef struct { } // Settings for the Gigadevice GD25Q16C 2MiB SPI flash. -// Datasheet: http://www.gigadevice.com/wp-content/uploads/2017/12/DS-00086-GD25Q16C-Rev2.6.pdf +// Datasheet: http://www.gigadevice.com/datasheet/gd25q16c/ #define GD25Q16C {\ .total_size = (1 << 21), /* 2 MiB */ \ .start_up_time_us = 5000, \ -- cgit v1.2.3 From 272be109140d9dda7697337de900e3afd8d90754 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 27 Nov 2018 23:29:30 -0800 Subject: Fetch back to 4.0.0-alpha.2 so Travis has the latest tags --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4c7c90b73..fcf5ca433 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: c compiler: - gcc git: - depth: 6 + depth: 1 # Each item under 'env' is a separate Travis job to execute. # They run in separate environments, so each one must take the time @@ -44,6 +44,9 @@ notifications: on_error: always before_script: + # Expand the git tree back to alpha 2 so we get intermediate tags + - git fetch --shallow-exclude=4.0.0-alpha.2 + - git describe --dirty --always --tags - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - sudo dpkg --add-architecture i386 -- cgit v1.2.3 From f4e7d7fbb4ded93b7c2b9542d41ef160b9154d53 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 27 Nov 2018 23:59:02 -0800 Subject: Try to get the last tag. --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fcf5ca433..09dab9ef3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -44,8 +44,10 @@ notifications: on_error: always before_script: - # Expand the git tree back to alpha 2 so we get intermediate tags - - git fetch --shallow-exclude=4.0.0-alpha.2 + # Expand the git tree back to the last tag. + - LAST_TAG=`git ls-remote --quiet --tags --sort=version:refname | egrep -o "refs/tags/[0-9]+.*\$" | tail -n 1` + - git fetch --shallow-exclude=$LAST_TAG + - git fetch --depth 1 $LAST_TAG - git describe --dirty --always --tags - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - sudo dpkg --add-architecture i386 -- cgit v1.2.3 From f13fac0fb4e0aea431c072c60936f27f05c723b1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 28 Nov 2018 00:19:17 -0800 Subject: try 3 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 09dab9ef3..396e194b7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -44,10 +44,10 @@ notifications: on_error: always before_script: - # Expand the git tree back to the last tag. + # Expand the git tree back to 4.0.0-alpha.1 and then fetch the latest tag. - LAST_TAG=`git ls-remote --quiet --tags --sort=version:refname | egrep -o "refs/tags/[0-9]+.*\$" | tail -n 1` - - git fetch --shallow-exclude=$LAST_TAG - - git fetch --depth 1 $LAST_TAG + - git fetch --shallow-exclude=4.0.0-alpha.1 + - git fetch --depth 1 origin $LAST_TAG:$LAST_TAG - git describe --dirty --always --tags - function var_search () { case "$1" in *$2*) true;; *) false;; esac; } - sudo dpkg --add-architecture i386 -- cgit v1.2.3