From 6c7723905c03f4f06b6ef7a56277d4dfec18ab4f Mon Sep 17 00:00:00 2001 From: Hierophect Date: Mon, 29 Jul 2019 11:21:35 -0400 Subject: [PATCH 1/3] Add temp status LEDs --- ports/stm32f4/supervisor/serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm32f4/supervisor/serial.c b/ports/stm32f4/supervisor/serial.c index 3154dc3e58..984db2d0f9 100644 --- a/ports/stm32f4/supervisor/serial.c +++ b/ports/stm32f4/supervisor/serial.c @@ -42,10 +42,10 @@ void serial_init(void) { huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) == HAL_OK) { - //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); } - //HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 5000); - //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); + HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 5000); + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); } bool serial_connected(void) { From e2fc55f829ba9e30ccf19c21d5aeacaf4a503fd6 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Wed, 31 Jul 2019 14:58:55 -0400 Subject: [PATCH 2/3] Add baseline HAL I2C support --- ports/stm32f4/Makefile | 1 + .../stm32f411re_discovery/mpconfigboard.mk | 3 +- .../stm32f412zg_discovery/stm32f4xx_hal_msp.c | 4 +- ports/stm32f4/common-hal/busio/I2C.c | 115 ++++++ ports/stm32f4/common-hal/busio/I2C.h | 44 ++ ports/stm32f4/common-hal/busio/OneWire.h | 33 ++ ports/stm32f4/common-hal/busio/SPI.c | 321 +++++++++++++++ ports/stm32f4/common-hal/busio/SPI.h | 42 ++ ports/stm32f4/common-hal/busio/UART.c | 375 ++++++++++++++++++ ports/stm32f4/common-hal/busio/UART.h | 46 +++ ports/stm32f4/common-hal/busio/__init__.c | 1 + ports/stm32f4/mpconfigport.mk | 1 + 12 files changed, 982 insertions(+), 4 deletions(-) create mode 100644 ports/stm32f4/common-hal/busio/I2C.c create mode 100644 ports/stm32f4/common-hal/busio/I2C.h create mode 100644 ports/stm32f4/common-hal/busio/OneWire.h create mode 100644 ports/stm32f4/common-hal/busio/SPI.c create mode 100644 ports/stm32f4/common-hal/busio/SPI.h create mode 100644 ports/stm32f4/common-hal/busio/UART.c create mode 100644 ports/stm32f4/common-hal/busio/UART.h create mode 100644 ports/stm32f4/common-hal/busio/__init__.c diff --git a/ports/stm32f4/Makefile b/ports/stm32f4/Makefile index 7f07444434..15fed7bde5 100755 --- a/ports/stm32f4/Makefile +++ b/ports/stm32f4/Makefile @@ -148,6 +148,7 @@ SRC_STM32 = \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_i2c.c \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_dma.c \ stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c \ diff --git a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk index 7b865b57e0..0d15aab498 100644 --- a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk +++ b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk @@ -9,5 +9,4 @@ MCU_SUB_VARIANT = stm32f411xe CMSIS_MCU = STM32F411xE LD_FILE = boards/STM32F411VETx_FLASH.ld TEXT0_ADDR = 0x08000000 -TEXT1_ADDR = 0x08020000 - +TEXT1_ADDR = 0x08020000 \ No newline at end of file diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c index 9d29f36079..54f444a71a 100644 --- a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c +++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c @@ -273,14 +273,14 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) */ GPIO_InitStruct.Pin = I2C2_SCL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Pull = GPIO_NOPULL;//GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; HAL_GPIO_Init(I2C2_SCL_GPIO_Port, &GPIO_InitStruct); GPIO_InitStruct.Pin = I2C2_SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Pull = GPIO_NOPULL;//GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF9_I2C2; HAL_GPIO_Init(I2C2_SDA_GPIO_Port, &GPIO_InitStruct); diff --git a/ports/stm32f4/common-hal/busio/I2C.c b/ports/stm32f4/common-hal/busio/I2C.c new file mode 100644 index 0000000000..8e1e57c36c --- /dev/null +++ b/ports/stm32f4/common-hal/busio/I2C.c @@ -0,0 +1,115 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "stm32f4xx_hal.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/shared/translate.h" + +I2C_HandleTypeDef hi2c2; + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) { + hi2c2.Instance = I2C2; + hi2c2.Init.ClockSpeed = 100000; + hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; + hi2c2.Init.OwnAddress1 = 0; + hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c2.Init.OwnAddress2 = 0; + hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if(HAL_I2C_Init(&hi2c2) != HAL_OK) { + mp_raise_RuntimeError(translate("I2C Init Error")); + } else { + mp_printf(&mp_plat_print, "I2C INIT OK"); + } + + self->sda_pin = sda->number; + self->scl_pin = scl->number; + + claim_pin(sda); + claim_pin(scl); +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda_pin == NO_PIN; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + + HAL_I2C_MspDeInit(&hi2c2); + + self->sda_pin = NO_PIN; + self->scl_pin = NO_PIN; +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + return HAL_I2C_IsDeviceReady(&hi2c2, (uint16_t)(addr<<1),2,2) == HAL_OK; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + bool grabbed_lock = false; + + //Critical section code that may be required at some point. + // uint32_t store_primask = __get_PRIMASK(); + // __disable_irq(); + // __DMB(); + + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + // __DMB(); + // __set_PRIMASK(store_primask); + + return grabbed_lock; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len, bool transmit_stop_bit) { + return HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)(addr<<1), (uint8_t *)data, (uint16_t)len, 2) == HAL_OK ? 0 : MP_EIO; +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + return HAL_I2C_Master_Receive(&hi2c2, (uint16_t)(addr<<1), data, (uint16_t)len, 2) == HAL_OK ? 0 : MP_EIO; +} diff --git a/ports/stm32f4/common-hal/busio/I2C.h b/ports/stm32f4/common-hal/busio/I2C.h new file mode 100644 index 0000000000..9fe0258a1c --- /dev/null +++ b/ports/stm32f4/common-hal/busio/I2C.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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_STM32F4_COMMON_HAL_BUSIO_I2C_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_I2C_H + +#include "common-hal/microcontroller/Pin.h" + +#include "stm32f4xx_hal.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + I2C_HandleTypeDef i2c_handle; + bool has_lock; + uint8_t scl_pin; + uint8_t sda_pin; +} busio_i2c_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/stm32f4/common-hal/busio/OneWire.h b/ports/stm32f4/common-hal/busio/OneWire.h new file mode 100644 index 0000000000..6e8c829793 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H + +// Use bitbangio. +#include "shared-module/busio/OneWire.h" + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_ONEWIRE_H diff --git a/ports/stm32f4/common-hal/busio/SPI.c b/ports/stm32f4/common-hal/busio/SPI.c new file mode 100644 index 0000000000..a8b9199842 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/SPI.c @@ -0,0 +1,321 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" + +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) { + // Sercom* sercom = NULL; + // uint8_t sercom_index; + // uint32_t clock_pinmux = 0; + // bool mosi_none = mosi == mp_const_none || mosi == NULL; + // bool miso_none = miso == mp_const_none || miso == NULL; + // uint32_t mosi_pinmux = 0; + // uint32_t miso_pinmux = 0; + // uint8_t clock_pad = 0; + // uint8_t mosi_pad = 0; + // uint8_t miso_pad = 0; + // uint8_t dopo = 255; + + // // Special case for SAMR boards. + // #ifdef PIN_PC19 + // if (miso == &pin_PC19) { + // if (mosi == &pin_PB30 && clock == &pin_PC18) { + // sercom = SERCOM4; + // sercom_index = 4; + // clock_pinmux = MUX_F; + // mosi_pinmux = MUX_F; + // miso_pinmux = MUX_F; + // clock_pad = 3; + // mosi_pad = 2; + // miso_pad = 0; + // dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + // } + // // Error, leave SERCOM unset to throw an exception later. + // } else { + // #endif + // for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + // sercom_index = clock->sercom[i].index; // 2 for SERCOM2, etc. + // if (sercom_index >= SERCOM_INST_NUM) { + // continue; + // } + // Sercom* potential_sercom = sercom_insts[sercom_index]; + // if ( + // #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102) + // (potential_sercom->SPI.CTRLA.bit.ENABLE != 0 && + // potential_sercom != status_apa102.spi_desc.dev.prvt && + // !apa102_sck_in_use)) { + // #else + // potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { + // #endif + // continue; + // } + // clock_pinmux = PINMUX(clock->number, (i == 0) ? MUX_C : MUX_D); + // clock_pad = clock->sercom[i].pad; + // if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { + // continue; + // } + // for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + // if (!mosi_none) { + // if (sercom_index == mosi->sercom[j].index) { + // mosi_pinmux = PINMUX(mosi->number, (j == 0) ? MUX_C : MUX_D); + // mosi_pad = mosi->sercom[j].pad; + // dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + // if (dopo > 0x3) { + // continue; // pad combination not possible + // } + // if (miso_none) { + // sercom = potential_sercom; + // break; + // } + // } else { + // continue; + // } + // } + // if (!miso_none) { + // for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + // if (sercom_index == miso->sercom[k].index) { + // miso_pinmux = PINMUX(miso->number, (k == 0) ? MUX_C : MUX_D); + // miso_pad = miso->sercom[k].pad; + // sercom = potential_sercom; + // break; + // } + // } + // } + // if (sercom != NULL) { + // break; + // } + // } + // if (sercom != NULL) { + // break; + // } + // } + // #ifdef PIN_PC19 + // } + // #endif + // if (sercom == NULL) { + // mp_raise_ValueError(translate("Invalid pins")); + // } + + // // Set up SPI clocks on SERCOM. + // samd_peripherals_sercom_clock_init(sercom, sercom_index); + + // #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102) + // // if we're re-using the dotstar sercom, make sure it is disabled or the init will fail out + // hri_sercomspi_clear_CTRLA_ENABLE_bit(sercom); + // #endif + // if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) { + // mp_raise_OSError(MP_EIO); + // } + + // // Pads must be set after spi_m_sync_init(), which uses default values from + // // the prototypical SERCOM. + // hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); + // hri_sercomspi_write_CTRLA_DIPO_bf(sercom, miso_pad); + + // // Always start at 250khz which is what SD cards need. They are sensitive to + // // SPI bus noise before they are put into SPI mode. + // uint8_t baud_value = samd_peripherals_spi_baudrate_to_baud_reg_value(250000); + // if (spi_m_sync_set_baudrate(&self->spi_desc, baud_value) != ERR_NONE) { + // // spi_m_sync_set_baudrate does not check for validity, just whether the device is + // // busy or not + // mp_raise_OSError(MP_EIO); + // } + + // gpio_set_pin_direction(clock->number, GPIO_DIRECTION_OUT); + // gpio_set_pin_pull_mode(clock->number, GPIO_PULL_OFF); + // gpio_set_pin_function(clock->number, clock_pinmux); + // claim_pin(clock); + // self->clock_pin = clock->number; + + // if (mosi_none) { + // self->MOSI_pin = NO_PIN; + // } else { + // gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT); + // gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); + // gpio_set_pin_function(mosi->number, mosi_pinmux); + // self->MOSI_pin = mosi->number; + // claim_pin(mosi); + // } + + // if (miso_none) { + // self->MISO_pin = NO_PIN; + // } else { + // gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN); + // gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); + // gpio_set_pin_function(miso->number, miso_pinmux); + // self->MISO_pin = miso->number; + // claim_pin(miso); + // } + + // 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; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + // if (common_hal_busio_spi_deinited(self)) { + // return; + // } + // allow_reset_sercom(self->spi_desc.dev.prvt); + + // spi_m_sync_disable(&self->spi_desc); + // spi_m_sync_deinit(&self->spi_desc); + // reset_pin_number(self->clock_pin); + // reset_pin_number(self->MOSI_pin); + // reset_pin_number(self->MISO_pin); + // self->clock_pin = NO_PIN; +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + // uint8_t baud_reg_value = samd_peripherals_spi_baudrate_to_baud_reg_value(baudrate); + + // void * hw = self->spi_desc.dev.prvt; + // // If the settings are already what we want then don't reset them. + // if (hri_sercomspi_get_CTRLA_CPHA_bit(hw) == phase && + // hri_sercomspi_get_CTRLA_CPOL_bit(hw) == polarity && + // hri_sercomspi_read_CTRLB_CHSIZE_bf(hw) == ((uint32_t)bits - 8) && + // hri_sercomspi_read_BAUD_BAUD_bf(hw) == baud_reg_value) { + // return true; + // } + + // // Disable, set values (most or all are enable-protected), and re-enable. + // spi_m_sync_disable(&self->spi_desc); + // hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + // hri_sercomspi_write_CTRLA_CPHA_bit(hw, phase); + // hri_sercomspi_write_CTRLA_CPOL_bit(hw, polarity); + // hri_sercomspi_write_CTRLB_CHSIZE_bf(hw, bits - 8); + // hri_sercomspi_write_BAUD_BAUD_bf(hw, baud_reg_value); + // hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + // spi_m_sync_enable(&self->spi_desc); + // hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool grabbed_lock = false; + // CRITICAL_SECTION_ENTER() + // if (!self->has_lock) { + // grabbed_lock = true; + // self->has_lock = true; + // } + // CRITICAL_SECTION_LEAVE(); + return grabbed_lock; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, size_t len) { + // if (len == 0) { + // return true; + // } + // int32_t status; + // if (len >= 16) { + // status = sercom_dma_write(self->spi_desc.dev.prvt, data, len); + // } else { + // struct io_descriptor *spi_io; + // spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io); + // status = spi_io->write(spi_io, data, len); + // } + return 0;//status >= 0; // Status is number of chars read or an error code < 0. +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + // if (len == 0) { + // return true; + // } + // int32_t status; + // if (len >= 16) { + // status = sercom_dma_read(self->spi_desc.dev.prvt, data, len, write_value); + // } else { + // self->spi_desc.dev.dummy_byte = write_value; + + // struct io_descriptor *spi_io; + // spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io); + + // status = spi_io->read(spi_io, data, len); + // } + return 0;//status >= 0; // Status is number of chars read or an error code < 0. +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) { + // if (len == 0) { + // return true; + // } + // int32_t status; + // if (len >= 16) { + // status = sercom_dma_transfer(self->spi_desc.dev.prvt, data_out, data_in, len); + // } else { + // struct spi_xfer xfer; + // xfer.txbuf = data_out; + // xfer.rxbuf = data_in; + // xfer.size = len; + // status = spi_m_sync_transfer(&self->spi_desc, &xfer); + // } + return 0;//status >= 0; // Status is number of chars read or an error code < 0. +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) { + return 0;//samd_peripherals_spi_baud_reg_value_to_baudrate(hri_sercomspi_read_BAUD_reg(self->spi_desc.dev.prvt)); +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) { + //void * hw = self->spi_desc.dev.prvt; + return 0;//hri_sercomspi_get_CTRLA_CPHA_bit(hw); +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) { + //void * hw = self->spi_desc.dev.prvt; + return 0;//hri_sercomspi_get_CTRLA_CPOL_bit(hw); +} diff --git a/ports/stm32f4/common-hal/busio/SPI.h b/ports/stm32f4/common-hal/busio/SPI.h new file mode 100644 index 0000000000..f7ff79b49b --- /dev/null +++ b/ports/stm32f4/common-hal/busio/SPI.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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_STM32F4_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bool has_lock; + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; +} busio_spi_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c new file mode 100644 index 0000000000..e9a4917150 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/UART.c @@ -0,0 +1,375 @@ +/* + * This file is part of the MicroPython 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/busio/UART.h" + +#include "mpconfigport.h" +#include "lib/utils/interrupt_char.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + +#include "tick.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, mp_float_t timeout, + uint8_t receiver_buffer_size) { + // Sercom* sercom = NULL; + // uint8_t sercom_index = 255; // Unset index + // uint32_t rx_pinmux = 0; + // uint8_t rx_pad = 255; // Unset pad + // uint32_t tx_pinmux = 0; + // uint8_t tx_pad = 255; // Unset pad + + // if (bits > 8) { + // mp_raise_NotImplementedError(translate("bytes > 8 bits not supported")); + // } + + // bool have_tx = tx != mp_const_none; + // bool have_rx = rx != mp_const_none; + // if (!have_tx && !have_rx) { + // mp_raise_ValueError(translate("tx and rx cannot both be None")); + // } + + // self->baudrate = baudrate; + // self->character_bits = bits; + // self->timeout_ms = timeout * 1000; + + // // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + + // for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + // Sercom* potential_sercom = NULL; + // if (have_tx) { + // sercom_index = tx->sercom[i].index; + // if (sercom_index >= SERCOM_INST_NUM) { + // continue; + // } + // potential_sercom = sercom_insts[sercom_index]; + // if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || + // !(tx->sercom[i].pad == 0 || + // tx->sercom[i].pad == 2)) { + // continue; + // } + // tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D); + // tx_pad = tx->sercom[i].pad; + // if (rx == mp_const_none) { + // sercom = potential_sercom; + // break; + // } + // } + // for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + // if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM && + // sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) || + // sercom_index == rx->sercom[j].index) && + // rx->sercom[j].pad != tx_pad) { + // rx_pinmux = PINMUX(rx->number, (j == 0) ? MUX_C : MUX_D); + // rx_pad = rx->sercom[j].pad; + // sercom = sercom_insts[rx->sercom[j].index]; + // sercom_index = rx->sercom[j].index; + // break; + // } + // } + // if (sercom != NULL) { + // break; + // } + // } + // if (sercom == NULL) { + // mp_raise_ValueError(translate("Invalid pins")); + // } + // if (!have_tx) { + // tx_pad = 0; + // if (rx_pad == 0) { + // tx_pad = 2; + // } + // } + // if (!have_rx) { + // rx_pad = (tx_pad + 1) % 4; + // } + + // // Set up clocks on SERCOM. + // samd_peripherals_sercom_clock_init(sercom, sercom_index); + + // if (rx && receiver_buffer_size > 0) { + // self->buffer_length = receiver_buffer_size; + // // Initially allocate the UART's buffer in the long-lived part of the + // // heap. UARTs are generally long-lived objects, but the "make long- + // // lived" machinery is incapable of moving internal pointers like + // // self->buffer, so do it manually. (However, as long as internal + // // pointers like this are NOT moved, allocating the buffer + // // in the long-lived pool is not strictly necessary) + // self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); + // if (self->buffer == NULL) { + // common_hal_busio_uart_deinit(self); + // mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + // } + // } else { + // self->buffer_length = 0; + // self->buffer = NULL; + // } + + // if (usart_async_init(usart_desc_p, sercom, self->buffer, self->buffer_length, NULL) != ERR_NONE) { + // mp_raise_ValueError(translate("Could not initialize UART")); + // } + + // // usart_async_init() sets a number of defaults based on a prototypical SERCOM + // // which don't necessarily match what we need. After calling it, set the values + // // specific to this instantiation of UART. + + // // Set pads computed for this SERCOM. + // // TXPO: + // // 0x0: TX pad 0; no RTS/CTS + // // 0x1: TX pad 2; no RTS/CTS + // // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 (not used by us right now) + // // So divide by 2 to map pad to value. + // // RXPO: + // // 0x0: RX pad 0 + // // 0x1: RX pad 1 + // // 0x2: RX pad 2 + // // 0x3: RX pad 3 + + // // Doing a group mask and set of the registers saves 60 bytes over setting the bitfields individually. + + // sercom->USART.CTRLA.reg &= ~(SERCOM_USART_CTRLA_TXPO_Msk | + // SERCOM_USART_CTRLA_RXPO_Msk | + // SERCOM_USART_CTRLA_FORM_Msk); + // sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(tx_pad / 2) | + // SERCOM_USART_CTRLA_RXPO(rx_pad) | + // (parity == PARITY_NONE ? 0 : SERCOM_USART_CTRLA_FORM(1)); + + // // Enable tx and/or rx based on whether the pins were specified. + // // CHSIZE is 0 for 8 bits, 5, 6, 7 for 5, 6, 7 bits. 1 for 9 bits, but we don't support that. + // sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_TXEN | + // SERCOM_USART_CTRLB_RXEN | + // SERCOM_USART_CTRLB_PMODE | + // SERCOM_USART_CTRLB_SBMODE | + // SERCOM_USART_CTRLB_CHSIZE_Msk); + // sercom->USART.CTRLB.reg |= (have_tx ? SERCOM_USART_CTRLB_TXEN : 0) | + // (have_rx ? SERCOM_USART_CTRLB_RXEN : 0) | + // (parity == PARITY_ODD ? SERCOM_USART_CTRLB_PMODE : 0) | + // (stop > 1 ? SERCOM_USART_CTRLB_SBMODE : 0) | + // SERCOM_USART_CTRLB_CHSIZE(bits % 8); + + // // Set baud rate + // common_hal_busio_uart_set_baudrate(self, baudrate); + + // // Turn on rx interrupt handling. The UART async driver has its own set of internal callbacks, + // // which are set up by uart_async_init(). These in turn can call user-specified callbacks. + // // In fact, the actual interrupts are not enabled unless we set up a user-specified callback. + // // This is confusing. It's explained in the Atmel START User Guide -> Implementation Description -> + // // Different read function behavior in some asynchronous drivers. As of this writing: + // // http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836 + // // Look at the ASFv4 code example for async USART. + // usart_async_register_callback(usart_desc_p, USART_ASYNC_RXC_CB, usart_async_rxc_callback); + + + // if (have_tx) { + // gpio_set_pin_direction(tx->number, GPIO_DIRECTION_OUT); + // gpio_set_pin_pull_mode(tx->number, GPIO_PULL_OFF); + // gpio_set_pin_function(tx->number, tx_pinmux); + // self->tx_pin = tx->number; + // claim_pin(tx); + // } else { + // self->tx_pin = NO_PIN; + // } + + // if (have_rx) { + // gpio_set_pin_direction(rx->number, GPIO_DIRECTION_IN); + // gpio_set_pin_pull_mode(rx->number, GPIO_PULL_OFF); + // gpio_set_pin_function(rx->number, rx_pinmux); + // self->rx_pin = rx->number; + // claim_pin(rx); + // } else { + // self->rx_pin = NO_PIN; + // } + + // usart_async_enable(usart_desc_p); +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return 0;//self->rx_pin == NO_PIN && self->tx_pin == NO_PIN; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + // if (common_hal_busio_uart_deinited(self)) { + // return; + // } + // // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + // usart_async_disable(usart_desc_p); + // usart_async_deinit(usart_desc_p); + // reset_pin_number(self->rx_pin); + // reset_pin_number(self->tx_pin); + // self->rx_pin = NO_PIN; + // self->tx_pin = NO_PIN; +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { +// if (self->rx_pin == NO_PIN) { +// mp_raise_ValueError(translate("No RX pin")); +// } + +// // This assignment is only here because the usart_async routines take a *const argument. +// struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + +// if (len == 0) { +// // Nothing to read. +// return 0; +// } + +// struct io_descriptor *io; +// usart_async_get_io_descriptor(usart_desc_p, &io); + +// size_t total_read = 0; +// uint64_t start_ticks = ticks_ms; + +// // Busy-wait until timeout or until we've read enough chars. +// while (ticks_ms - start_ticks <= self->timeout_ms) { +// // Read as many chars as we can right now, up to len. +// size_t num_read = io_read(io, data, len); + +// // Advance pointer in data buffer, and decrease how many chars left to read. +// data += num_read; +// len -= num_read; +// total_read += num_read; +// if (len == 0) { +// // Don't need to read any more: data buf is full. +// break; +// } +// if (num_read > 0) { +// // Reset the timeout on every character read. +// start_ticks = ticks_ms; +// } +// #ifdef MICROPY_VM_HOOK_LOOP +// MICROPY_VM_HOOK_LOOP ; +// // Allow user to break out of a timeout with a KeyboardInterrupt. +// if (mp_hal_is_interrupted()) { +// break; +// } +// #endif +// // If we are zero timeout, make sure we don't loop again (in the event +// // we read in under 1ms) +// if (self->timeout_ms == 0) { +// break; +// } +// } + +// if (total_read == 0) { +// *errcode = EAGAIN; +// return MP_STREAM_ERROR; +// } + + return 0;//total_read; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + // if (self->tx_pin == NO_PIN) { + // mp_raise_ValueError(translate("No TX pin")); + // } + + // // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + + // struct io_descriptor *io; + // usart_async_get_io_descriptor(usart_desc_p, &io); + + // if (io_write(io, data, len) < 0) { + // *errcode = MP_EAGAIN; + // return MP_STREAM_ERROR; + // } + + // // Wait until write is complete or timeout. + // bool done = false; + // uint64_t start_ticks = ticks_ms; + // // Busy-wait for timeout. + // while (ticks_ms - start_ticks < self->timeout_ms) { + // if (usart_async_is_tx_empty(usart_desc_p)) { + // done = true; + // break; + // } + // #ifdef MICROPY_VM_HOOK_LOOP + // MICROPY_VM_HOOK_LOOP + // #endif + // } + + // if (!done) { + // *errcode = MP_EAGAIN; + // return MP_STREAM_ERROR; + // } + + // // All the characters got written. + return 0;//len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return 0;//self->baudrate; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + // usart_async_set_baud_rate(usart_desc_p, + // // Samples and ARITHMETIC vs FRACTIONAL must correspond to USART_SAMPR in + // // hpl_sercom_config.h. + // _usart_async_calculate_baud_rate(baudrate, // e.g. 9600 baud + // PROTOTYPE_SERCOM_USART_ASYNC_CLOCK_FREQUENCY, + // 16, // samples + // USART_BAUDRATE_ASYNCH_ARITHMETIC, + // 0 // fraction - not used for ARITHMETIC + // )); + // self->baudrate = baudrate; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + // // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + // struct usart_async_status async_status; + // usart_async_get_status(usart_desc_p, &async_status); + return 0;//async_status.rxcnt; +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + // This assignment is only here because the usart_async routines take a *const argument. + // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + // usart_async_flush_rx_buffer(usart_desc_p); + +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + // if (self->tx_pin == NO_PIN) { + // return false; + // } + // // This assignment is only here because the usart_async routines take a *const argument. + // const struct _usart_async_device * const usart_device_p = + // (struct _usart_async_device * const) &self->usart_desc.device; + return 0;//_usart_async_is_byte_sent(usart_device_p); +} diff --git a/ports/stm32f4/common-hal/busio/UART.h b/ports/stm32f4/common-hal/busio/UART.h new file mode 100644 index 0000000000..6992339340 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/UART.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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_STM32F4_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +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; + uint32_t buffer_length; + uint8_t* buffer; +} busio_uart_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_BUSIO_UART_H diff --git a/ports/stm32f4/common-hal/busio/__init__.c b/ports/stm32f4/common-hal/busio/__init__.c new file mode 100644 index 0000000000..41761b6743 --- /dev/null +++ b/ports/stm32f4/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk index 814bb2b207..88423c6d66 100644 --- a/ports/stm32f4/mpconfigport.mk +++ b/ports/stm32f4/mpconfigport.mk @@ -19,4 +19,5 @@ ifeq ($(MCU_SUB_VARIANT), stm32f412zx) CIRCUITPY_BOARD = 1 CIRCUITPY_DIGITALIO = 1 CIRCUITPY_MICROCONTROLLER = 1 + CIRCUITPY_BUSIO = 1 endif From 06d53ef8a7eac57f46fd1895642731237ab72ec1 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Wed, 31 Jul 2019 17:06:44 -0400 Subject: [PATCH 3/3] minor debugging changes --- ports/stm32f4/supervisor/serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm32f4/supervisor/serial.c b/ports/stm32f4/supervisor/serial.c index 984db2d0f9..1532a8ae88 100644 --- a/ports/stm32f4/supervisor/serial.c +++ b/ports/stm32f4/supervisor/serial.c @@ -33,7 +33,7 @@ UART_HandleTypeDef huart2; void serial_init(void) { huart2.Instance = USART2; - huart2.Init.BaudRate = 9600; + huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; @@ -44,7 +44,7 @@ void serial_init(void) { { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); } - HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 5000); + HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 2); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); } @@ -54,7 +54,7 @@ bool serial_connected(void) { char serial_read(void) { uint8_t data; - HAL_UART_Receive(&huart2, &data, 1,5000); + HAL_UART_Receive(&huart2, &data, 1,500); return data; }