diff options
| author | Lucian Copeland <hierophect@gmail.com> | 2020-03-16 12:37:53 -0400 |
|---|---|---|
| committer | Lucian Copeland <hierophect@gmail.com> | 2020-03-16 12:37:53 -0400 |
| commit | bb3ed3a827f70582f9a19ceb359b169d1b50262a (patch) | |
| tree | 0d4ad5ee42de9bfb7c3b2cbb8b0d41d9f285298b /ports/stm | |
| parent | bb167f04fa06ca7245c3f173d4ce108e36309c67 (diff) | |
| parent | 3a5f79acef1fd109aeb93e06e8a22dac5d54aa24 (diff) | |
Merge branch 'master' into stm32x7-setup
Diffstat (limited to 'ports/stm')
| -rwxr-xr-x | ports/stm/Makefile | 87 | ||||
| -rw-r--r-- | ports/stm/common-hal/pulseio/PulseIn.c | 238 | ||||
| -rw-r--r-- | ports/stm/common-hal/pulseio/PulseIn.h | 3 | ||||
| m--------- | ports/stm/st_driver | 0 | ||||
| m--------- | ports/stm/stm32f4 | 0 | ||||
| -rw-r--r-- | ports/stm/supervisor/port.c | 2 |
6 files changed, 278 insertions, 52 deletions
diff --git a/ports/stm/Makefile b/ports/stm/Makefile index 3a6191c85..f8c05fd80 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -66,10 +66,10 @@ INC += -I. INC += -I../.. INC += -I$(BUILD) INC += -I$(BUILD)/genhdr -INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc -INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc/Legacy -INC += -I./stm32f4/CMSIS/Device/ST/STM32F4xx/Include -INC += -I./stm32f4/CMSIS/Include +INC += -I./st_driver/STM32F4xx_HAL_Driver/Inc +INC += -I./st_driver/STM32F4xx_HAL_Driver/Inc/Legacy +INC += -I./st_driver/CMSIS/Device/ST/STM32F4xx/Include +INC += -I./st_driver/CMSIS/Include INC += -I./boards INC += -I./boards/$(BOARD) INC += -I./peripherals @@ -147,46 +147,45 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32F4 -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD ###################################### SRC_STM32 = \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.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_ll_sdmmc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usart.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_rcc.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_utils.c \ - stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_i2c.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_dma.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usart.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_rcc.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_utils.c \ + st_driver/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c \ system_stm32f4xx.c diff --git a/ports/stm/common-hal/pulseio/PulseIn.c b/ports/stm/common-hal/pulseio/PulseIn.c index 068936bdd..8428a2278 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.c +++ b/ports/stm/common-hal/pulseio/PulseIn.c @@ -34,46 +34,270 @@ #include "shared-bindings/pulseio/PulseIn.h" #include "tick.h" +#include "stm32f4xx_hal.h" + +#define STM32_GPIO_PORT_SIZE 16 + +static pulseio_pulsein_obj_t* _objs[STM32_GPIO_PORT_SIZE]; + +static void assign_EXTI_Interrupt(pulseio_pulsein_obj_t* self, uint8_t num); + +static void pulsein_handler(uint8_t num) { + // Interrupt register must be cleared manually + EXTI->PR = 1 << num; + + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + // current_tick gives us the remaining us until the next tick but we want the number since the last ms. + current_us = 1000 - current_us; + + pulseio_pulsein_obj_t* self = _objs[num]; + if ( !self ) return; + + if (self->first_edge) { + // first pulse is opposite state from idle + bool state = HAL_GPIO_ReadPin(pin_port(self->pin->port), pin_mask(self->pin->number)); + if ( self->idle_state != state ) { + self->first_edge = false; + } + } else { + uint32_t ms_diff = current_ms - self->last_ms; + uint16_t us_diff = current_us - self->last_us; + uint32_t total_diff = us_diff; + + if (self->last_us > current_us) { + total_diff = 1000 + current_us - self->last_us; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + } else { + total_diff += ms_diff * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + + self->last_ms = current_ms; + self->last_us = current_us; +} + void pulsein_reset(void) { + // Disable all active interrupts and clear array + for (uint i = 0; i < STM32_GPIO_PORT_SIZE; i++) { + if (_objs[i] != NULL) { + HAL_NVIC_DisableIRQ(_objs[i]->irq); + } + } + memset(_objs, 0, sizeof(_objs)); } void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { - mp_raise_NotImplementedError(translate("PulseIn not yet supported")); + // STM32 has one shared EXTI for each pin number, 0-15 + uint8_t p_num = pin->number; + if(_objs[p_num]) { + mp_raise_ValueError(translate("Pin number already reserved by EXTI")); + } + _objs[p_num] = self; + + // Allocate pulse buffer + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), + maxlen * sizeof(uint16_t)); + } + + // Set internal variables + self->pin = pin; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->paused = false; + self->last_us = 0; + self->last_ms = 0; + + // EXTI pins can also be read as an input + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin_mask(pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct); + + // Interrupt starts immediately + assign_EXTI_Interrupt(self, pin->number); + HAL_NVIC_EnableIRQ(self->irq); + claim_pin(pin); } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { - return true; + return (self->pin == NULL); } void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } + //Remove pulsein slot from shared array + HAL_NVIC_DisableIRQ(self->irq); + _objs[self->pin->number] = NULL; + reset_pin_number(self->pin->port, self->pin->number); + self->pin = NULL; } void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { + HAL_NVIC_DisableIRQ(self->irq); + self->paused = true; } void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) { + // Make sure we're paused. + if ( !self->paused ) { + common_hal_pulseio_pulsein_pause(self); + } + + // Send the trigger pulse. + if (trigger_duration > 0) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin_mask(self->pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(pin_port(self->pin->port), &GPIO_InitStruct); + + HAL_GPIO_WritePin(pin_port(self->pin->port), pin_mask(self->pin->number), !self->idle_state); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + HAL_GPIO_WritePin(pin_port(self->pin->port), pin_mask(self->pin->number), self->idle_state); + + GPIO_InitStruct.Pin = pin_mask(self->pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(pin_port(self->pin->port), &GPIO_InitStruct); + } + + self->first_edge = true; + self->paused = false; + self->last_ms = 0; + self->last_us = 0; + + HAL_NVIC_EnableIRQ(self->irq); } void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + HAL_NVIC_DisableIRQ(self->irq); + self->start = 0; + self->len = 0; + HAL_NVIC_EnableIRQ(self->irq); } uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { - return 0; + HAL_NVIC_DisableIRQ(self->irq); + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + HAL_NVIC_EnableIRQ(self->irq); + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + HAL_NVIC_EnableIRQ(self->irq); + return value; } uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { - return 0; + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + HAL_NVIC_DisableIRQ(self->irq); + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + HAL_NVIC_EnableIRQ(self->irq); + + return value; } uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { - return 0; + return self->maxlen; } bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { - return 0; + return self->paused; } uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { - return 0; + return self->len; +} + +static void assign_EXTI_Interrupt(pulseio_pulsein_obj_t* self, uint8_t num) { + if (num == 0) { + self->irq = EXTI0_IRQn; + } else if (num == 1) { + self->irq = EXTI1_IRQn; + } else if (num == 2) { + self->irq = EXTI2_IRQn; + } else if (num == 3) { + self->irq = EXTI3_IRQn; + } else if (num == 4) { + self->irq = EXTI4_IRQn; + } else if (num >= 5 && num <= 9 ) { + self->irq = EXTI9_5_IRQn; + } else if (num >= 10 && num <= 15) { + self->irq = EXTI15_10_IRQn; + } +} + +void EXTI0_IRQHandler(void) +{ + pulsein_handler(0); +} +void EXTI1_IRQHandler(void) +{ + pulsein_handler(1); +} +void EXTI2_IRQHandler(void) +{ + pulsein_handler(2); +} +void EXTI3_IRQHandler(void) +{ + pulsein_handler(3); +} +void EXTI4_IRQHandler(void) +{ + pulsein_handler(4); +} + +void EXTI9_5_IRQHandler(void) +{ + uint32_t pending = EXTI->PR; + for (uint i = 5; i <= 9; i++) { + if(pending & (1 << i)) { + pulsein_handler(i); + } + } +} + +void EXTI15_10_IRQHandler(void) +{ + uint32_t pending = EXTI->PR; + for (uint i = 10; i <= 15; i++) { + if(pending & (1 << i)) { + pulsein_handler(i); + } + } } diff --git a/ports/stm/common-hal/pulseio/PulseIn.h b/ports/stm/common-hal/pulseio/PulseIn.h index 2538b07ab..5456613c6 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.h +++ b/ports/stm/common-hal/pulseio/PulseIn.h @@ -34,7 +34,8 @@ typedef struct { mp_obj_base_t base; - uint8_t pin; + const mcu_pin_obj_t* pin; + IRQn_Type irq; bool idle_state; bool paused; volatile bool first_edge; diff --git a/ports/stm/st_driver b/ports/stm/st_driver new file mode 160000 +Subproject 3fc2e0f3db155b33177bb0705e0dd65cadb5841 diff --git a/ports/stm/stm32f4 b/ports/stm/stm32f4 deleted file mode 160000 -Subproject 89a356f0b44883d55c45a5d22940777a44a2b88 diff --git a/ports/stm/supervisor/port.c b/ports/stm/supervisor/port.c index ecb4d3d15..948e9f2e4 100644 --- a/ports/stm/supervisor/port.c +++ b/ports/stm/supervisor/port.c @@ -36,6 +36,7 @@ #include "common-hal/busio/UART.h" #include "common-hal/pulseio/PWMOut.h" #include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PulseIn.h" #include "stm32f4/clocks.h" #include "stm32f4/gpio.h" @@ -62,6 +63,7 @@ void reset_port(void) { uart_reset(); pwmout_reset(); pulseout_reset(); + pulsein_reset(); } void reset_to_bootloader(void) { |
