summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atmel-samd/Makefile4
-rw-r--r--atmel-samd/asf/sam0/drivers/sercom/usart/usart.c26
-rw-r--r--atmel-samd/boards/feather_m0_flash/pins.c6
-rw-r--r--atmel-samd/boards/metro_m0_flash/mpconfigboard.mk2
-rw-r--r--atmel-samd/common-hal/nativeio/SPI.c4
-rw-r--r--atmel-samd/common-hal/nativeio/UART.c368
-rw-r--r--atmel-samd/common-hal/nativeio/types.h16
-rw-r--r--atmel-samd/mpconfigport.h2
-rw-r--r--atmel-samd/samd21_pins.c3
-rw-r--r--atmel-samd/samd21_pins.h2
-rw-r--r--cc3200/mods/modwlan.c3
-rw-r--r--cc3200/mods/pybuart.c2
-rw-r--r--py/ioctl.h38
-rw-r--r--shared-bindings/nativeio/UART.c291
-rw-r--r--shared-bindings/nativeio/UART.h60
-rw-r--r--shared-bindings/nativeio/__init__.c2
-rw-r--r--stmhal/can.c2
-rw-r--r--stmhal/modnwcc3k.c2
-rw-r--r--stmhal/moduselect.c2
-rw-r--r--stmhal/pybioctl.h8
-rw-r--r--stmhal/uart.c4
-rw-r--r--stmhal/usb.c2
22 files changed, 811 insertions, 38 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile
index ba9204355..a7d93ae56 100644
--- a/atmel-samd/Makefile
+++ b/atmel-samd/Makefile
@@ -106,7 +106,7 @@ CFLAGS_CORTEX_M0 = \
-DSYSTICK_MODE \
-DEXTINT_CALLBACK_MODE=true \
-DUDD_ENABLE \
- -DUSART_CALLBACK_MODE=true \
+ -DUSART_CALLBACK_MODE=false \
-DSPI_CALLBACK_MODE=false \
-DI2C_MASTER_CALLBACK_MODE=false \
-DDAC_CALLBACK_MODE=false \
@@ -155,7 +155,6 @@ SRC_ASF = $(addprefix asf/sam0/,\
drivers/sercom/sercom_interrupt.c \
drivers/sercom/spi/spi.c \
drivers/sercom/usart/usart.c \
- drivers/sercom/usart/usart_interrupt.c \
drivers/system/clock/clock_samd21_r21_da/clock.c \
drivers/system/clock/clock_samd21_r21_da/gclk.c \
drivers/system/interrupt/system_interrupt.c \
@@ -219,6 +218,7 @@ SRC_BINDINGS = \
nativeio/I2C.c \
nativeio/PWMOut.c \
nativeio/SPI.c \
+ nativeio/UART.c \
neopixel_write/__init__.c \
time/__init__.c
diff --git a/atmel-samd/asf/sam0/drivers/sercom/usart/usart.c b/atmel-samd/asf/sam0/drivers/sercom/usart/usart.c
index e0abee9b8..ab1c3bacf 100644
--- a/atmel-samd/asf/sam0/drivers/sercom/usart/usart.c
+++ b/atmel-samd/asf/sam0/drivers/sercom/usart/usart.c
@@ -187,7 +187,7 @@ static enum status_code _usart_set_config(
}
/* Set stopbits and enable transceivers */
- ctrlb =
+ ctrlb =
#ifdef FEATURE_USART_IRDA
(config->encoding_format_enable << SERCOM_USART_CTRLB_ENC_Pos) |
#endif
@@ -207,18 +207,18 @@ static enum status_code _usart_set_config(
ctrla |= SERCOM_USART_CTRLA_TXINV | SERCOM_USART_CTRLA_RXINV;
}
ctrlb |= USART_CHARACTER_SIZE_8BIT;
-
+
switch(config->iso7816_config.protocol_t) {
case ISO7816_PROTOCOL_T_0:
- ctrlb |= (uint32_t)config->stopbits;
+ ctrlb |= (uint32_t)config->stopbits;
ctrlc |= SERCOM_USART_CTRLC_GTIME(config->iso7816_config.guard_time) | \
(config->iso7816_config.inhibit_nack) | \
(config->iso7816_config.successive_recv_nack) | \
SERCOM_USART_CTRLC_MAXITER(config->iso7816_config.max_iterations);
- break;
+ break;
case ISO7816_PROTOCOL_T_1:
ctrlb |= USART_STOPBITS_1;
- break;
+ break;
}
} else {
#endif
@@ -334,8 +334,8 @@ enum status_code usart_init(
SercomUsart *const usart_hw = &(module->hw->USART);
uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
- uint32_t pm_index, gclk_index;
-#if (SAML22) || (SAMC20)
+ uint32_t pm_index, gclk_index;
+#if (SAML22) || (SAMC20)
pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
#elif (SAML21) || (SAMR30)
@@ -348,7 +348,7 @@ enum status_code usart_init(
}
#elif (SAMC21)
pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
-
+
if (sercom_index == 5){
gclk_index = SERCOM5_GCLK_ID_CORE;
} else {
@@ -374,7 +374,7 @@ enum status_code usart_init(
if (sercom_index == 5) {
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBD, 1 << pm_index);
} else {
- system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
+ system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
}
#else
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
@@ -639,8 +639,8 @@ enum status_code usart_read_wait(
* \param[in] tx_data Pointer to data to transmit
* \param[in] length Number of characters to transmit
*
- * \note If using 9-bit data, the array that *tx_data point to should be defined
- * as uint16_t array and should be casted to uint8_t* pointer. Because it
+ * \note If using 9-bit data, the array that *tx_data point to should be defined
+ * as uint16_t array and should be casted to uint8_t* pointer. Because it
* is an address pointer, the highest byte is not discarded. For example:
* \code
#define TX_LEN 3
@@ -733,8 +733,8 @@ enum status_code usart_write_buffer_wait(
* \param[out] rx_data Pointer to receive buffer
* \param[in] length Number of characters to receive
*
- * \note If using 9-bit data, the array that *rx_data point to should be defined
- * as uint16_t array and should be casted to uint8_t* pointer. Because it
+ * \note If using 9-bit data, the array that *rx_data point to should be defined
+ * as uint16_t array and should be casted to uint8_t* pointer. Because it
* is an address pointer, the highest byte is not discarded. For example:
* \code
#define RX_LEN 3
diff --git a/atmel-samd/boards/feather_m0_flash/pins.c b/atmel-samd/boards/feather_m0_flash/pins.c
index 8eac1713f..06a245ca4 100644
--- a/atmel-samd/boards/feather_m0_flash/pins.c
+++ b/atmel-samd/boards/feather_m0_flash/pins.c
@@ -10,8 +10,10 @@ STATIC const mp_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PB11 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PB10 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA12 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_0RX), (mp_obj_t)&pin_PA11 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_1TX), (mp_obj_t)&pin_PA10 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA11 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA11 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA10 },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA10 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PA22 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PA23 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PA15 },
diff --git a/atmel-samd/boards/metro_m0_flash/mpconfigboard.mk b/atmel-samd/boards/metro_m0_flash/mpconfigboard.mk
index 8b6d61bbb..4b508957d 100644
--- a/atmel-samd/boards/metro_m0_flash/mpconfigboard.mk
+++ b/atmel-samd/boards/metro_m0_flash/mpconfigboard.mk
@@ -1,4 +1,4 @@
-LD_FILE = boards/samd21x18-bootloader-external-flash.ld
+LD_FILE = boards/samd21x18-external-flash.ld
USB_VID = 0x239A
USB_PID = 0x8015
diff --git a/atmel-samd/common-hal/nativeio/SPI.c b/atmel-samd/common-hal/nativeio/SPI.c
index f31bae1e1..70b096579 100644
--- a/atmel-samd/common-hal/nativeio/SPI.c
+++ b/atmel-samd/common-hal/nativeio/SPI.c
@@ -125,12 +125,12 @@ void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self,
&config_spi_master.pinmux_pad3};
*pinmuxes[clock_pad] = clock_pinmux;
self->clock_pin = clock->pin;
- self->MOSI_pin = 0;
+ self->MOSI_pin = NO_PIN;
if (!mosi_none) {
*pinmuxes[mosi_pad] = mosi_pinmux;
self->MOSI_pin = mosi->pin;
}
- self->MISO_pin = 0;
+ self->MISO_pin = NO_PIN;
if (!miso_none) {
*pinmuxes[miso_pad] = miso_pinmux;
self->MISO_pin = miso->pin;
diff --git a/atmel-samd/common-hal/nativeio/UART.c b/atmel-samd/common-hal/nativeio/UART.c
new file mode 100644
index 000000000..8fd4e0b4a
--- /dev/null
+++ b/atmel-samd/common-hal/nativeio/UART.c
@@ -0,0 +1,368 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 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 "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/nativeio/UART.h"
+
+#include "py/gc.h"
+#include "py/mperrno.h"
+#include "py/nlr.h"
+#include "py/stream.h"
+#include "samd21_pins.h"
+#include "tick.h"
+
+#include "asf/sam0/drivers/sercom/sercom_interrupt.h"
+
+#undef ENABLE
+
+nativeio_uart_obj_t *_uart_instances[SERCOM_INST_NUM];
+
+static void _sercom_default_handler(
+ const uint8_t instance)
+{
+ Assert(false);
+}
+
+static void _nativeio_uart_interrupt_handler(uint8_t instance)
+{
+ /* Temporary variables */
+ uint16_t interrupt_status;
+ uint8_t error_code;
+
+ /* Get device instance from the look-up table */
+ struct usart_module *module
+ = (struct usart_module *)_sercom_instances[instance];
+
+ nativeio_uart_obj_t *self = _uart_instances[instance];
+
+ /* Pointer to the hardware module instance */
+ SercomUsart *const usart_hw = &(module->hw->USART);
+
+ /* Wait for the synchronization to complete */
+ _usart_wait_for_sync(module);
+
+ /* Read and mask interrupt flag register */
+ interrupt_status = usart_hw->INTFLAG.reg;
+ interrupt_status &= usart_hw->INTENSET.reg;
+
+ /* Check if the Receive Complete interrupt has occurred, and that
+ * there's more data to receive */
+ if (interrupt_status & SERCOM_USART_INTFLAG_RXC) {
+ /* Read out the status code and mask away all but the 4 LSBs*/
+ error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);
+ /* CTS status should not be considered as an error */
+ if(error_code & SERCOM_USART_STATUS_CTS) {
+ error_code &= ~SERCOM_USART_STATUS_CTS;
+ }
+ /* Check if an error has occurred during the receiving */
+ if (error_code) {
+ /* Check which error occurred */
+ if (error_code & SERCOM_USART_STATUS_FERR) {
+ /* Store the error code and clear flag by writing 1 to it */
+ usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR;
+ } else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
+ /* Store the error code and clear flag by writing 1 to it */
+ usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF;
+ } else if (error_code & SERCOM_USART_STATUS_PERR) {
+ /* Store the error code and clear flag by writing 1 to it */
+ usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR;
+ }
+ self->rx_error = true;
+ } else {
+ /* Read current packet from DATA register,
+ * increment buffer pointer and decrement buffer length */
+ uint16_t received_data = (usart_hw->DATA.reg & SERCOM_USART_DATA_MASK);
+
+ common_hal_mcu_disable_interrupts();
+ /* Read value will be at least 8-bits long */
+ uint32_t buffer_end = (self->buffer_start + self->buffer_size) % self->buffer_length;
+ self->buffer[buffer_end] = received_data;
+ self->buffer_size++;
+
+ if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
+ /* 9-bit data, write next received byte to the buffer */
+ self->buffer[buffer_end + 1] = (received_data >> 8);
+ self->buffer_size++;
+ }
+
+ if (self->buffer_size > self->buffer_length) {
+ self->buffer_start++;
+ if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
+ self->buffer_start++;
+ }
+ self->buffer_size = self->buffer_length;
+ }
+ common_hal_mcu_enable_interrupts();
+ }
+ }
+}
+
+void common_hal_nativeio_uart_construct(nativeio_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) {
+ Sercom* sercom = NULL;
+ uint32_t rx_pinmux = PINMUX_UNUSED;
+ uint8_t rx_pad = 5; // Unset pad
+ uint32_t tx_pinmux = PINMUX_UNUSED;
+ uint8_t tx_pad = 5; // Unset pad
+ for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
+ Sercom* potential_sercom = NULL;
+ if (tx != NULL) {
+ potential_sercom = tx->sercom[i].sercom;
+ if (potential_sercom == NULL ||
+ potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 ||
+ !(tx->sercom[i].pad == 0 ||
+ tx->sercom[i].pad == 2)) {
+ continue;
+ }
+ tx_pinmux = PINMUX(tx->pin, (i == 0) ? MUX_C : MUX_D);
+ tx_pad = tx->sercom[i].pad;
+ if (rx == NULL) {
+ sercom = potential_sercom;
+ break;
+ }
+ }
+ for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
+ if (((tx == NULL && rx->sercom[j].sercom->I2CM.CTRLA.bit.ENABLE == 0) ||
+ potential_sercom == rx->sercom[j].sercom) &&
+ rx->sercom[j].pad != tx_pad) {
+ rx_pinmux = PINMUX(rx->pin, (j == 0) ? MUX_C : MUX_D);
+ rx_pad = rx->sercom[j].pad;
+ sercom = rx->sercom[j].sercom;
+ break;
+ }
+ }
+ if (sercom != NULL) {
+ break;
+ }
+ }
+ if (sercom == NULL) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
+ "No hardware support available with those pins."));
+ }
+ if (tx == NULL) {
+ tx_pad = 0;
+ if (rx_pad == 0) {
+ tx_pad = 2;
+ }
+ }
+ if (rx == NULL) {
+ rx_pad = (tx_pad + 1) % 4;
+ }
+ struct usart_config config_usart;
+ usart_get_config_defaults(&config_usart);
+ config_usart.mux_setting = (SERCOM_USART_CTRLA_RXPO(rx_pad) | SERCOM_USART_CTRLA_TXPO(tx_pad / 2));
+
+ if (parity == PARITY_ODD) {
+ config_usart.parity = USART_PARITY_ODD;
+ } else if (parity == PARITY_EVEN) {
+ config_usart.parity = USART_PARITY_EVEN;
+ }
+ config_usart.stopbits = stop - 1;
+ config_usart.character_size = bits % 8;
+ config_usart.baudrate = baudrate;
+
+ // Map pad to pinmux through a short array.
+ uint32_t *pinmuxes[4] = {&config_usart.pinmux_pad0,
+ &config_usart.pinmux_pad1,
+ &config_usart.pinmux_pad2,
+ &config_usart.pinmux_pad3};
+ // Pin muxes have a default pin, set them to unused so that no other pins are changed.
+ for (int i = 0; i < 4; i++) {
+ *pinmuxes[i] = PINMUX_UNUSED;
+ }
+
+ self->rx_pin = NO_PIN;
+ config_usart.receiver_enable = rx != NULL;
+ if (rx != NULL) {
+ *pinmuxes[rx_pad] = rx_pinmux;
+ self->rx_pin = rx->pin;
+ }
+
+ self->tx_pin = NO_PIN;
+ config_usart.transmitter_enable = tx != NULL;
+ if (tx != NULL) {
+ *pinmuxes[tx_pad] = tx_pinmux;
+ self->tx_pin = tx->pin;
+ }
+
+ self->timeout_ms = timeout;
+
+ self->buffer_length = receiver_buffer_size;
+ self->buffer_length *= (bits + 7) / 8;
+ self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false);
+ if (self->buffer == NULL) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
+ "Unable to allocate RX buffer."));
+ }
+
+ if (usart_init(&self->uart_instance, sercom, &config_usart) != STATUS_OK) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Unable to init UART"));
+ }
+
+ // We use our own interrupt handler because we want a circular buffer
+ // instead of the jobs that ASF provides.
+ uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw);
+ _sercom_set_handler(instance_index, _nativeio_uart_interrupt_handler);
+ _sercom_instances[instance_index] = &self->uart_instance;
+ _uart_instances[instance_index] = self;
+
+ /* Enable Global interrupt for module */
+ system_interrupt_enable(_sercom_get_interrupt_vector(self->uart_instance.hw));
+
+ usart_enable(&self->uart_instance);
+ self->uart_instance.hw->USART.INTENSET.bit.RXC = true;
+}
+
+void common_hal_nativeio_uart_deinit(nativeio_uart_obj_t *self) {
+ self->uart_instance.hw->USART.INTENCLR.bit.RXC = true;
+
+ uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw);
+ _sercom_set_handler(instance_index, &_sercom_default_handler);
+ _sercom_instances[instance_index] = NULL;
+ _uart_instances[instance_index] = NULL;
+
+ system_interrupt_disable(_sercom_get_interrupt_vector(self->uart_instance.hw));
+
+ usart_disable(&self->uart_instance);
+ reset_pin(self->rx_pin);
+ reset_pin(self->tx_pin);
+}
+
+// Read characters.
+size_t common_hal_nativeio_uart_read(nativeio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
+ size_t total_read = 0;
+ uint64_t start_ticks = ticks_ms;
+ while (total_read < len && ticks_ms - start_ticks < self->timeout_ms) {
+ if (self->buffer_size > 0) {
+ common_hal_mcu_disable_interrupts();
+ data[total_read] = self->buffer[self->buffer_start];
+ if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) {
+ data[total_read + 1] = self->buffer[self->buffer_start + 1];
+ self->buffer_start += 2;
+ self->buffer_size -= 2;
+ } else {
+ self->buffer_start++;
+ self->buffer_size--;
+ }
+ self->buffer_start = self->buffer_start % self->buffer_length;
+ common_hal_mcu_enable_interrupts();
+ // Reset the timeout every character read.
+ total_read++;
+ start_ticks = ticks_ms;
+ }
+ }
+ if (total_read == 0) {
+ *errcode = MP_EAGAIN;
+ return MP_STREAM_ERROR;
+ }
+ return total_read;
+}
+
+// Write characters.
+size_t common_hal_nativeio_uart_write(nativeio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
+ /* Check that the transmitter is enabled */
+ if (!(self->uart_instance.transmitter_enabled)) {
+ *errcode = MP_EIO;
+ return MP_STREAM_ERROR;
+ }
+
+ /* Get a pointer to the hardware module instance */
+ SercomUsart *const usart_hw = &(self->uart_instance.hw->USART);
+
+ /* Wait until synchronization is complete */
+ _usart_wait_for_sync(&self->uart_instance);
+
+ uint16_t tx_pos = 0;
+
+ bool ok = true;
+ uint64_t start_ticks = 0;
+ /* Blocks while buffer is being transferred */
+ while (len--) {
+ /* Wait for the USART to be ready for new data and abort
+ * operation if it doesn't get ready within the timeout*/
+ ok = false;
+ start_ticks = ticks_ms;
+ while (ticks_ms - start_ticks < self->timeout_ms) {
+ if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) {
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok) {
+ break;
+ }
+
+ /* Data to send is at least 8 bits long */
+ uint16_t data_to_send = data[tx_pos++];
+
+ /* Check if the character size exceeds 8 bit */
+ if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) {
+ data_to_send |= (data[tx_pos++] << 8);
+ }
+
+ /* Send the data through the USART module */
+
+ enum status_code status = usart_write_wait(&self->uart_instance, data_to_send);
+ if (status != STATUS_OK) {
+ ok = false;
+ }
+ }
+
+ /* Wait until Transmit is complete or timeout */
+ if (ok) {
+ ok = false;
+ start_ticks = ticks_ms;
+ while (ticks_ms - start_ticks < self->timeout_ms) {
+ if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) {
+ ok = true;
+ break;
+ }
+ }
+ }
+
+ if (!ok && tx_pos == 0) {
+ *errcode = MP_EAGAIN;
+ return MP_STREAM_ERROR;
+ }
+ return tx_pos;
+}
+
+uint32_t common_hal_nativeio_uart_rx_characters_available(nativeio_uart_obj_t *self) {
+ if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) {
+ return self->buffer_size / 2;
+ }
+ return self->buffer_size;
+}
+
+bool common_hal_nativeio_uart_ready_to_tx(nativeio_uart_obj_t *self) {
+ if (!(self->uart_instance.transmitter_enabled)) {
+ return false;
+ }
+ return self->uart_instance.hw->USART.INTFLAG.bit.DRE;
+}
diff --git a/atmel-samd/common-hal/nativeio/types.h b/atmel-samd/common-hal/nativeio/types.h
index 365345a2e..9f83effb1 100644
--- a/atmel-samd/common-hal/nativeio/types.h
+++ b/atmel-samd/common-hal/nativeio/types.h
@@ -42,6 +42,7 @@
#include "asf/sam0/drivers/dac/dac.h"
#include "asf/sam0/drivers/sercom/i2c/i2c_master.h"
#include "asf/sam0/drivers/sercom/spi/spi.h"
+#include "asf/sam0/drivers/sercom/usart/usart.h"
#include "asf/sam0/drivers/tc/tc.h"
#include "asf/sam0/drivers/tcc/tcc.h"
// Only support TouchIn when external SPI flash is used.
@@ -103,4 +104,19 @@ typedef struct {
#endif
} nativeio_touchin_obj_t;
+typedef struct {
+ mp_obj_base_t base;
+ struct usart_module uart_instance;
+ uint8_t rx_pin;
+ uint8_t tx_pin;
+ uint32_t timeout_ms;
+ bool rx_error;
+ // 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;
+} nativeio_uart_obj_t;
+
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__
diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h
index 1f05a88b5..8bb93bf19 100644
--- a/atmel-samd/mpconfigport.h
+++ b/atmel-samd/mpconfigport.h
@@ -51,7 +51,7 @@
#define MICROPY_PY_DESCRIPTORS (1)
#define MICROPY_PY_FRAMEBUF (1)
#define MICROPY_PY_MATH (1)
-#define MICROPY_PY_CMATH (1)
+#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_URANDOM (1)
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
diff --git a/atmel-samd/samd21_pins.c b/atmel-samd/samd21_pins.c
index bdfc0ae83..dc1aad269 100644
--- a/atmel-samd/samd21_pins.c
+++ b/atmel-samd/samd21_pins.c
@@ -59,6 +59,9 @@ const mcu_pin_obj_t pin_## p_name = { \
#define NO_ADC_INPUT (0)
void reset_pin(uint8_t pin) {
+ if (pin >= PORT_BITS) {
+ return;
+ }
struct system_pinmux_config config;
system_pinmux_get_config_defaults(&config);
config.powersave = true;
diff --git a/atmel-samd/samd21_pins.h b/atmel-samd/samd21_pins.h
index ab34d8929..0c7522e8b 100644
--- a/atmel-samd/samd21_pins.h
+++ b/atmel-samd/samd21_pins.h
@@ -11,6 +11,8 @@ void reset_pin(uint8_t pin);
#define MUX_F 5
#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux))
+#define NO_PIN PORT_BITS
+
// Pins in datasheet order.
#ifdef PIN_PA00
extern const mcu_pin_obj_t pin_PA00;
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index 4b3dd4ec3..7381ebb17 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -29,6 +29,7 @@
#include "std.h"
#include "simplelink.h"
+#include "py/ioctl.h"
#include "py/mpconfig.h"
#include "py/obj.h"
#include "py/objstr.h"
@@ -45,7 +46,6 @@
#include "modnetwork.h"
#include "modusocket.h"
#include "modwlan.h"
-#include "pybioctl.h"
#include "pybrtc.h"
#include "debug.h"
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
@@ -1511,4 +1511,3 @@ int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t
}
return ret;
}
-
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index 493522f83..c2f32cc3e 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -46,7 +46,7 @@
#include "uart.h"
#include "pybuart.h"
#include "mpirq.h"
-#include "pybioctl.h"
+#include "py/ioctl.h"
#include "pybsleep.h"
#include "mpexception.h"
#include "py/mpstate.h"
diff --git a/py/ioctl.h b/py/ioctl.h
new file mode 100644
index 000000000..fe9162dec
--- /dev/null
+++ b/py/ioctl.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2015 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_PY_IOCTL_H__
+#define __MICROPY_INCLUDED_PY_IOCTL_H__
+
+#define MP_IOCTL_POLL (0x100 | 1)
+
+// These values are compatible with Linux, which are in turn
+// compatible with iBCS2 spec.
+#define MP_IOCTL_POLL_RD (0x0001)
+#define MP_IOCTL_POLL_WR (0x0004)
+#define MP_IOCTL_POLL_ERR (0x0008)
+#define MP_IOCTL_POLL_HUP (0x0010)
+
+#endif // __MICROPY_INCLUDED_PY_IOCTL_H__
diff --git a/shared-bindings/nativeio/UART.c b/shared-bindings/nativeio/UART.c
new file mode 100644
index 000000000..3d0e7f475
--- /dev/null
+++ b/shared-bindings/nativeio/UART.c
@@ -0,0 +1,291 @@
+/*
+ * This file is part of the Micro Python 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 <stdint.h>
+
+#include "shared-bindings/nativeio/UART.h"
+
+#include "py/ioctl.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+
+//| .. currentmodule:: nativeio
+//|
+//| :class:`UART` -- a bidirectional serial protocol
+//| =================================================
+//|
+//|
+//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1000, receiver_buffer_size=64)
+//|
+//| A common bidirectional serial protocol that uses an an agreed upon speed
+//| rather than a shared clock line.
+//|
+//| :param ~microcontroller.Pin tx: the pin to transmit with
+//| :param ~microcontroller.Pin rx: the pin to receive on
+//| :param int baudrate: the transmit and receive speed
+/// :param int bits: the number of bits per byte, 7, 8 or 9.
+/// :param int parity: the parity used for error checking, `None`, 0 (even) or 1 (odd).
+/// :param int stop: the number of stop bits, 1 or 2.
+/// :param int timeout: the timeout in milliseconds to wait for the first character and between subsequent characters.
+/// :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
+//|
+typedef struct {
+ mp_obj_base_t base;
+} nativeio_uart_parity_obj_t;
+extern const nativeio_uart_parity_obj_t nativeio_uart_parity_even_obj;
+extern const nativeio_uart_parity_obj_t nativeio_uart_parity_odd_obj;
+
+STATIC mp_obj_t nativeio_uart_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, MP_OBJ_FUN_ARGS_MAX, true);
+ nativeio_uart_obj_t *self = m_new_obj(nativeio_uart_obj_t);
+ self->base.type = &nativeio_uart_type;
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+ enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size};
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9600} },
+ { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
+ { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
+ { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
+ };
+ 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);
+
+ assert_pin(args[ARG_rx].u_obj, true);
+ const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj);
+ assert_pin_free(rx);
+
+ assert_pin(args[ARG_tx].u_obj, true);
+ const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj);
+ assert_pin_free(tx);
+
+ uint8_t bits = args[ARG_bits].u_int;
+ if (bits < 7 || bits > 9) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
+ "bits must be 7, 8 or 9"));
+ }
+
+ uart_parity_t parity = PARITY_NONE;
+ if (args[ARG_baudrate].u_obj == &nativeio_uart_parity_even_obj) {
+ parity = PARITY_EVEN;
+ } else if (args[ARG_baudrate].u_obj == &nativeio_uart_parity_odd_obj) {
+ parity = PARITY_ODD;
+ }
+
+ uint8_t stop = args[ARG_stop].u_int;
+ if (stop != 1 && stop != 2) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
+ "stop must be 1 or 2"));
+ }
+
+ common_hal_nativeio_uart_construct(self, tx, rx,
+ args[ARG_baudrate].u_int, bits, parity, stop, args[ARG_timeout].u_int,
+ args[ARG_receiver_buffer_size].u_int);
+ return (mp_obj_t)self;
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the UART and releases any hardware resources for reuse.
+//|
+STATIC mp_obj_t nativeio_uart_obj_deinit(mp_obj_t self_in) {
+ nativeio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_nativeio_uart_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_uart_deinit_obj, nativeio_uart_obj_deinit);
+
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+STATIC mp_obj_t nativeio_uart_obj___enter__(mp_obj_t self_in) {
+ return self_in;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_uart___enter___obj, nativeio_uart_obj___enter__);
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context.
+//|
+STATIC mp_obj_t nativeio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_nativeio_uart_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_uart___exit___obj, 4, 4, nativeio_uart_obj___exit__);
+
+// These are standard stream methods. Code is in py/stream.c.
+//
+//| .. method:: read([nbytes])
+//|
+//| Read characters. If ``nbytes`` is specified then read at most that many bytes.
+//|
+//| :return: Data read
+//| :rtype: bytes or None
+//|
+//| .. method:: readall()
+//|
+//| Reads much has been buffered.
+//|
+//| :return: Data buffered so far
+//| :rtype: bytes or None
+//|
+//| .. method:: readinto(buf[, nbytes])
+//|
+//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
+//| that many bytes. Otherwise, read at most ``len(buf)`` bytes.
+//|
+//| :return: number of bytes read and stored into ``buf``
+//| :rtype: bytes or None
+//|
+//| .. method:: readline()
+//|
+//| Read a line, ending in a newline character.
+//|
+//| :return: the line read
+//| :rtype: int or None
+//|
+//| .. method:: write(buf)
+//|
+//| Write the buffer of bytes to the bus.
+//|
+//| :return: the number of bytes written
+//| :rtype: int or None
+//|
+
+// These three methods are used by the shared stream methods.
+STATIC mp_uint_t nativeio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+ nativeio_uart_obj_t *self = self_in;
+ byte *buf = buf_in;
+
+ // make sure we want at least 1 char
+ if (size == 0) {
+ return 0;
+ }
+
+ return common_hal_nativeio_uart_read(self, buf, size, errcode);
+}
+
+STATIC mp_uint_t nativeio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+ nativeio_uart_obj_t *self = self_in;
+ const byte *buf = buf_in;
+
+ return common_hal_nativeio_uart_write(self, buf, size, errcode);
+}
+
+STATIC mp_uint_t nativeio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+ nativeio_uart_obj_t *self = self_in;
+ mp_uint_t ret;
+ if (request == MP_IOCTL_POLL) {
+ mp_uint_t flags = arg;
+ ret = 0;
+ if ((flags & MP_IOCTL_POLL_RD) && common_hal_nativeio_uart_rx_characters_available(self) > 0) {
+ ret |= MP_IOCTL_POLL_RD;
+ }
+ if ((flags & MP_IOCTL_POLL_WR) && common_hal_nativeio_uart_ready_to_tx(self)) {
+ ret |= MP_IOCTL_POLL_WR;
+ }
+ } else {
+ *errcode = MP_EINVAL;
+ ret = MP_STREAM_ERROR;
+ }
+ return ret;
+}
+
+//| .. class:: nativeio.UART.Parity
+//|
+//| Enum-like class to define the parity used to verify correct data transfer.
+//|
+//| .. data:: odd
+//|
+//| Total number of ones should be odd.
+//|
+//| .. data:: even
+//|
+//| Total number of ones should be even.
+//|
+const mp_obj_type_t nativeio_uart_parity_type;
+
+const nativeio_uart_parity_obj_t nativeio_uart_parity_odd_obj = {
+ { &nativeio_uart_parity_type },
+};
+
+const nativeio_uart_parity_obj_t nativeio_uart_parity_even_obj = {
+ { &nativeio_uart_parity_type },
+};
+
+STATIC const mp_rom_map_elem_t nativeio_uart_parity_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_odd), MP_ROM_PTR(&nativeio_uart_parity_odd_obj) },
+ { MP_ROM_QSTR(MP_QSTR_even), MP_ROM_PTR(&nativeio_uart_parity_even_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(nativeio_uart_parity_locals_dict, nativeio_uart_parity_locals_dict_table);
+
+const mp_obj_type_t nativeio_uart_parity_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Parity,
+ .locals_dict = (mp_obj_t)&nativeio_uart_parity_locals_dict,
+};
+
+STATIC const mp_rom_map_elem_t nativeio_uart_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_uart_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&nativeio_uart___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_uart___exit___obj) },
+
+ // Standard stream methods.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+
+ // Nested Enum-like Classes.
+ { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&nativeio_uart_parity_type) },
+};
+STATIC MP_DEFINE_CONST_DICT(nativeio_uart_locals_dict, nativeio_uart_locals_dict_table);
+
+STATIC const mp_stream_p_t uart_stream_p = {
+ .read = nativeio_uart_read,
+ .write = nativeio_uart_write,
+ .ioctl = nativeio_uart_ioctl,
+ .is_text = false,
+};
+
+const mp_obj_type_t nativeio_uart_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_UART,
+ .make_new = nativeio_uart_make_new,
+ .getiter = mp_identity,
+ .iternext = mp_stream_unbuffered_iter,
+ .protocol = &uart_stream_p,
+ .locals_dict = (mp_obj_dict_t*)&nativeio_uart_locals_dict,
+};
diff --git a/shared-bindings/nativeio/UART.h b/shared-bindings/nativeio/UART.h
new file mode 100644
index 000000000..bafc5b730
--- /dev/null
+++ b/shared-bindings/nativeio/UART.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the Micro Python 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.
+ */
+
+#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__
+#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__
+
+#include "common-hal/microcontroller/types.h"
+#include "common-hal/nativeio/types.h"
+
+extern const mp_obj_type_t nativeio_uart_type;
+
+typedef enum {
+ PARITY_NONE,
+ PARITY_EVEN,
+ PARITY_ODD
+} uart_parity_t;
+
+// Construct an underlying UART object.
+extern void common_hal_nativeio_uart_construct(nativeio_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);
+
+extern void common_hal_nativeio_uart_deinit(nativeio_uart_obj_t *self);
+
+// Read characters. len is in characters NOT bytes!
+extern size_t common_hal_nativeio_uart_read(nativeio_uart_obj_t *self,
+ uint8_t *data, size_t len, int *errcode);
+
+// Write characters. len is in characters NOT bytes!
+extern size_t common_hal_nativeio_uart_write(nativeio_uart_obj_t *self,
+ const uint8_t *data, size_t len, int *errcode);
+
+extern uint32_t common_hal_nativeio_uart_rx_characters_available(nativeio_uart_obj_t *self);
+extern bool common_hal_nativeio_uart_ready_to_tx(nativeio_uart_obj_t *self);
+
+#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__
diff --git a/shared-bindings/nativeio/__init__.c b/shared-bindings/nativeio/__init__.c
index 0cf4ec829..9bcc252cd 100644
--- a/shared-bindings/nativeio/__init__.c
+++ b/shared-bindings/nativeio/__init__.c
@@ -42,6 +42,7 @@
#include "shared-bindings/nativeio/PWMOut.h"
#include "shared-bindings/nativeio/SPI.h"
#include "shared-bindings/nativeio/TouchIn.h"
+#include "shared-bindings/nativeio/UART.h"
#include "common-hal/nativeio/types.h"
#include "shared-bindings/nativeio/__init__.h"
@@ -116,6 +117,7 @@ STATIC const mp_rom_map_elem_t nativeio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_PWMOut), MP_ROM_PTR(&nativeio_pwmout_type) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&nativeio_spi_type) },
{ MP_ROM_QSTR(MP_QSTR_TouchIn), MP_ROM_PTR(&nativeio_touchin_type) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&nativeio_uart_type) },
};
STATIC MP_DEFINE_CONST_DICT(nativeio_module_globals, nativeio_module_globals_table);
diff --git a/stmhal/can.c b/stmhal/can.c
index 88d66b653..8bb008bc6 100644
--- a/stmhal/can.c
+++ b/stmhal/can.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <stdarg.h>
+#include "py/ioctl.h"
#include "py/nlr.h"
#include "py/objtuple.h"
#include "py/runtime.h"
@@ -36,7 +37,6 @@
#include "py/mphal.h"
#include "bufhelper.h"
#include "can.h"
-#include "pybioctl.h"
#include "irq.h"
#if MICROPY_HW_ENABLE_CAN
diff --git a/stmhal/modnwcc3k.c b/stmhal/modnwcc3k.c
index 591057602..936404e5f 100644
--- a/stmhal/modnwcc3k.c
+++ b/stmhal/modnwcc3k.c
@@ -30,6 +30,7 @@
// CC3000 defines its own ENOBUFS (different to standard one!)
#undef ENOBUFS
+#include "py/ioctl.h"
#include "py/nlr.h"
#include "py/objtuple.h"
#include "py/objlist.h"
@@ -41,7 +42,6 @@
#include "pin.h"
#include "genhdr/pins.h"
#include "spi.h"
-#include "pybioctl.h"
#include "hci.h"
#include "socket.h"
diff --git a/stmhal/moduselect.c b/stmhal/moduselect.c
index 0d76953c6..97e2f4417 100644
--- a/stmhal/moduselect.c
+++ b/stmhal/moduselect.c
@@ -26,12 +26,12 @@
#include <stdio.h>
+#include "py/ioctl.h"
#include "py/runtime.h"
#include "py/obj.h"
#include "py/objlist.h"
#include "py/mperrno.h"
#include "py/mphal.h"
-#include "pybioctl.h"
// Flags for poll()
#define FLAG_ONESHOT (1)
diff --git a/stmhal/pybioctl.h b/stmhal/pybioctl.h
deleted file mode 100644
index b71e04ed5..000000000
--- a/stmhal/pybioctl.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define MP_IOCTL_POLL (0x100 | 1)
-
-// These values are compatible with Linux, which are in turn
-// compatible with iBCS2 spec.
-#define MP_IOCTL_POLL_RD (0x0001)
-#define MP_IOCTL_POLL_WR (0x0004)
-#define MP_IOCTL_POLL_ERR (0x0008)
-#define MP_IOCTL_POLL_HUP (0x0010)
diff --git a/stmhal/uart.c b/stmhal/uart.c
index cbcb7c059..a485f4463 100644
--- a/stmhal/uart.c
+++ b/stmhal/uart.c
@@ -28,13 +28,13 @@
#include <string.h>
#include <stdarg.h>
+#include "py/ioctl.h"
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "uart.h"
-#include "pybioctl.h"
#include "irq.h"
//TODO: Add UART7/8 support for MCU_SERIES_F7
@@ -563,7 +563,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
self->read_buf_len = args.read_buf_len.u_int + 1; // +1 to adjust for usable length of buffer
self->read_buf = m_new(byte, self->read_buf_len << self->char_width);
__HAL_UART_ENABLE_IT(&self->uart, UART_IT_RXNE);
- HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_UART, IRQ_SUBPRI_UART);
+ HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_UART, IRQ_SUBPRI_UART);
HAL_NVIC_EnableIRQ(self->irqn);
}
diff --git a/stmhal/usb.c b/stmhal/usb.c
index 4eb67a8ca..21f718bc9 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -34,13 +34,13 @@
#include "usbd_msc_storage.h"
#include "usbd_hid_interface.h"
+#include "py/ioctl.h"
#include "py/objstr.h"
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "bufhelper.h"
#include "usb.h"
-#include "pybioctl.h"
#if defined(USE_USB_FS)
#define USB_PHY_ID USB_PHY_FS_ID