diff --git a/src/Makefile b/src/Makefile index d500e14fb..cf2f5a944 100755 --- a/src/Makefile +++ b/src/Makefile @@ -152,6 +152,11 @@ MPY_CFLAGS += -DMICROPY_PY_TV=1 MICROPY_ARGS += MICROPY_PY_TV=1 endif +ifeq ($(MICROPY_PY_BUZZER), 1) +MPY_CFLAGS += -DMICROPY_PY_BUZZER=1 +MICROPY_ARGS += MICROPY_PY_BUZZER=1 +endif + # Include the port Makefile. include $(OMV_DIR)/ports/$(PORT)/omv_portconfig.mk diff --git a/src/micropython b/src/micropython index 2d1323048..56358108e 160000 --- a/src/micropython +++ b/src/micropython @@ -1 +1 @@ -Subproject commit 2d1323048adbbba9d90ec263e463951118c75643 +Subproject commit 56358108e100a9a1a16caee3de089bb8bbdb43f7 diff --git a/src/omv/boards/BORMIO/omv_boardconfig.mk b/src/omv/boards/BORMIO/omv_boardconfig.mk index 5ffa6600a..f48905c68 100755 --- a/src/omv/boards/BORMIO/omv_boardconfig.mk +++ b/src/omv/boards/BORMIO/omv_boardconfig.mk @@ -23,3 +23,4 @@ MICROPY_PY_AUDIO = 0 MICROPY_PY_MICRO_SPEECH = 0 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/boards/NANO33/omv_boardconfig.mk b/src/omv/boards/NANO33/omv_boardconfig.mk index 0d6eb9b93..25aded9da 100755 --- a/src/omv/boards/NANO33/omv_boardconfig.mk +++ b/src/omv/boards/NANO33/omv_boardconfig.mk @@ -16,4 +16,5 @@ MICROPY_PY_ULAB=1 MICROPY_PY_AUDIO=1 MICROPY_PY_LCD = 0 MICROPY_PY_TV = 0 +MICROPY_PY_BUZZER = 0 MICROPY_PY_SENSOR = 1 diff --git a/src/omv/boards/OPENMV2/omv_boardconfig.mk b/src/omv/boards/OPENMV2/omv_boardconfig.mk index d435a0544..b0a6b9079 100755 --- a/src/omv/boards/OPENMV2/omv_boardconfig.mk +++ b/src/omv/boards/OPENMV2/omv_boardconfig.mk @@ -16,3 +16,4 @@ MICROPY_PY_SENSOR = 1 MICROPY_PY_WINC1500 = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/boards/OPENMV3/omv_boardconfig.mk b/src/omv/boards/OPENMV3/omv_boardconfig.mk index 886b3b5a8..e760a81a3 100755 --- a/src/omv/boards/OPENMV3/omv_boardconfig.mk +++ b/src/omv/boards/OPENMV3/omv_boardconfig.mk @@ -17,3 +17,4 @@ MICROPY_PY_ULAB = 1 MICROPY_PY_WINC1500 = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/boards/OPENMV4/omv_boardconfig.mk b/src/omv/boards/OPENMV4/omv_boardconfig.mk index 9021546a1..c32635280 100755 --- a/src/omv/boards/OPENMV4/omv_boardconfig.mk +++ b/src/omv/boards/OPENMV4/omv_boardconfig.mk @@ -18,3 +18,4 @@ MICROPY_PY_WINC1500 = 1 MICROPY_PY_IMU = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/boards/OPENMV4P/omv_boardconfig.mk b/src/omv/boards/OPENMV4P/omv_boardconfig.mk index 73140d409..8ee10f2ef 100755 --- a/src/omv/boards/OPENMV4P/omv_boardconfig.mk +++ b/src/omv/boards/OPENMV4P/omv_boardconfig.mk @@ -17,3 +17,4 @@ MICROPY_PY_ULAB = 1 MICROPY_PY_WINC1500 = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/boards/OPENMVPT/omv_boardconfig.h b/src/omv/boards/OPENMVPT/omv_boardconfig.h index f2bd551a5..1189bca9e 100644 --- a/src/omv/boards/OPENMVPT/omv_boardconfig.h +++ b/src/omv/boards/OPENMVPT/omv_boardconfig.h @@ -620,6 +620,20 @@ #define OMV_FIR_LEPTON_MCLK_TIM_RELEASE_RESET() __HAL_RCC_TIM15_RELEASE_RESET() #define OMV_FIR_LEPTON_MCLK_TIM_PCLK_FREQ() HAL_RCC_GetPCLK2Freq() +// Buzzer +#define OMV_BUZZER_PIN (GPIO_PIN_1) +#define OMV_BUZZER_PORT (GPIOA) +#define OMV_BUZZER_ALT (GPIO_AF1_TIM2) +#define OMV_BUZZER_FREQ (4000) + +#define OMV_BUZZER_TIM (TIM2) +#define OMV_BUZZER_TIM_CHANNEL (TIM_CHANNEL_2) +#define OMV_BUZZER_TIM_CLK_ENABLE() __HAL_RCC_TIM2_CLK_ENABLE() +#define OMV_BUZZER_TIM_CLK_DISABLE() __HAL_RCC_TIM2_CLK_DISABLE() +#define OMV_BUZZER_TIM_FORCE_RESET() __HAL_RCC_TIM2_FORCE_RESET() +#define OMV_BUZZER_TIM_RELEASE_RESET() __HAL_RCC_TIM2_RELEASE_RESET() +#define OMV_BUZZER_TIM_PCLK_FREQ() HAL_RCC_GetPCLK1Freq() + // Enable additional GPIO banks for DRAM... #define OMV_ENABLE_GPIO_BANK_F #define OMV_ENABLE_GPIO_BANK_G diff --git a/src/omv/boards/OPENMVPT/omv_boardconfig.mk b/src/omv/boards/OPENMVPT/omv_boardconfig.mk index 73140d409..80432a70a 100755 --- a/src/omv/boards/OPENMVPT/omv_boardconfig.mk +++ b/src/omv/boards/OPENMVPT/omv_boardconfig.mk @@ -17,3 +17,4 @@ MICROPY_PY_ULAB = 1 MICROPY_PY_WINC1500 = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 1 diff --git a/src/omv/boards/PORTENTA/omv_boardconfig.mk b/src/omv/boards/PORTENTA/omv_boardconfig.mk index 026fd5ece..f787ee9b1 100755 --- a/src/omv/boards/PORTENTA/omv_boardconfig.mk +++ b/src/omv/boards/PORTENTA/omv_boardconfig.mk @@ -22,3 +22,4 @@ MICROPY_PY_AUDIO = 1 MICROPY_PY_MICRO_SPEECH = 1 MICROPY_PY_LCD = 1 MICROPY_PY_TV = 1 +MICROPY_PY_BUZZER = 0 diff --git a/src/omv/ports/stm32/main.c b/src/omv/ports/stm32/main.c index 221f5f6fb..03439ed2e 100644 --- a/src/omv/ports/stm32/main.c +++ b/src/omv/ports/stm32/main.c @@ -71,6 +71,7 @@ #include "py_lcd.h" #include "py_fir.h" #include "py_tv.h" +#include "py_buzzer.h" #include "py_imu.h" #include "py_audio.h" @@ -498,6 +499,9 @@ soft_reset: py_lcd_init0(); py_fir_init0(); py_tv_init0(); + #if MICROPY_PY_BUZZER + py_buzzer_init0(); + #endif // MICROPY_PY_BUZZER imlib_init_all(); readline_init0(); pin_init0(); diff --git a/src/omv/ports/stm32/modules/py_buzzer.c b/src/omv/ports/stm32/modules/py_buzzer.c new file mode 100644 index 000000000..80c26aa9e --- /dev/null +++ b/src/omv/ports/stm32/modules/py_buzzer.c @@ -0,0 +1,112 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Buzzer Python module. + */ +#include "py/obj.h" + +#include "omv_boardconfig.h" +#include STM32_HAL_H + +#if MICROPY_PY_BUZZER + +static TIM_HandleTypeDef buzzer_tim_handle = {}; + +static int buzzer_freq = OMV_BUZZER_FREQ; +static int buzzer_duty = 0; + +static void buzzer_setup(int freq, int duty) +{ + int tclk = OMV_BUZZER_TIM_PCLK_FREQ() * 2; + int period = (tclk / freq) - 1; + int pulse = (period * duty) / 510; + + if (((buzzer_duty <= 0) || (255 < buzzer_duty)) && (0 < duty) && (duty <= 255)) { + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Alternate = OMV_BUZZER_ALT; + GPIO_InitStructure.Pin = OMV_BUZZER_PIN; + HAL_GPIO_Init(OMV_BUZZER_PORT, &GPIO_InitStructure); + + buzzer_tim_handle.Instance = OMV_BUZZER_TIM; + buzzer_tim_handle.Init.Prescaler = 0; + buzzer_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP; + buzzer_tim_handle.Init.Period = period; + buzzer_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + buzzer_tim_handle.Init.RepetitionCounter = 0; + buzzer_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + + TIM_OC_InitTypeDef buzzer_tim_oc_handle; + buzzer_tim_oc_handle.Pulse = pulse; + buzzer_tim_oc_handle.OCMode = TIM_OCMODE_PWM1; + buzzer_tim_oc_handle.OCPolarity = TIM_OCPOLARITY_HIGH; + buzzer_tim_oc_handle.OCNPolarity = TIM_OCNPOLARITY_HIGH; + buzzer_tim_oc_handle.OCFastMode = TIM_OCFAST_DISABLE; + buzzer_tim_oc_handle.OCIdleState = TIM_OCIDLESTATE_RESET; + buzzer_tim_oc_handle.OCNIdleState = TIM_OCNIDLESTATE_RESET; + + HAL_TIM_PWM_Init(&buzzer_tim_handle); + HAL_TIM_PWM_ConfigChannel(&buzzer_tim_handle, &buzzer_tim_oc_handle, OMV_BUZZER_TIM_CHANNEL); + HAL_TIM_PWM_Start(&buzzer_tim_handle, OMV_BUZZER_TIM_CHANNEL); + } else if ((0 < buzzer_duty) && (buzzer_duty <= 255) && ((duty <= 0) || (255 < duty))) { + HAL_TIM_PWM_Stop(&buzzer_tim_handle, OMV_BUZZER_TIM_CHANNEL); + HAL_TIM_PWM_DeInit(&buzzer_tim_handle); + HAL_GPIO_DeInit(OMV_BUZZER_PORT, OMV_BUZZER_PIN); + } else if ((0 < buzzer_duty) && (buzzer_duty <= 255) && (0 < duty) && (duty <= 255)) { + __HAL_TIM_SET_AUTORELOAD(&buzzer_tim_handle, period); + __HAL_TIM_SET_COMPARE(&buzzer_tim_handle, OMV_BUZZER_TIM_CHANNEL, pulse); + } + + buzzer_freq = freq; + buzzer_duty = duty; +} + +STATIC mp_obj_t py_buzzer_freq(uint n_args, const mp_obj_t *args) +{ + if (!n_args) { + return mp_obj_new_int(buzzer_freq); + } else { + buzzer_setup(mp_obj_get_int(*args), buzzer_duty); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_buzzer_freq_obj, 0, 1, py_buzzer_freq); + +STATIC mp_obj_t py_buzzer_duty(uint n_args, const mp_obj_t *args) +{ + if (!n_args) { + return mp_obj_new_int(buzzer_duty); + } else { + buzzer_setup(buzzer_freq, mp_obj_get_int(*args)); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_buzzer_duty_obj, 0, 1, py_buzzer_duty); + +static const mp_rom_map_elem_t globals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_buzzer) }, + { MP_ROM_QSTR(MP_QSTR_RESONANT_FREQ), MP_ROM_INT(OMV_BUZZER_FREQ) }, + { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&py_buzzer_freq_obj) }, + { MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&py_buzzer_duty_obj) } +}; + +STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table); + +const mp_obj_module_t buzzer_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_t) &globals_dict, +}; + +void py_buzzer_init0() +{ + buzzer_setup(OMV_BUZZER_FREQ, 0); +} + +#endif // MICROPY_PY_BUZZER diff --git a/src/omv/ports/stm32/modules/py_buzzer.h b/src/omv/ports/stm32/modules/py_buzzer.h new file mode 100644 index 000000000..a253d3cbd --- /dev/null +++ b/src/omv/ports/stm32/modules/py_buzzer.h @@ -0,0 +1,14 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Buzzer Python module. + */ +#ifndef __PY_BUZZER_H__ +#define __PY_BUZZER_H__ +void py_buzzer_init0(); +#endif // __PY_BUZZER_H__ diff --git a/src/omv/ports/stm32/stm32fxxx_hal_msp.c b/src/omv/ports/stm32/stm32fxxx_hal_msp.c index d9eabb080..75ef64138 100644 --- a/src/omv/ports/stm32/stm32fxxx_hal_msp.c +++ b/src/omv/ports/stm32/stm32fxxx_hal_msp.c @@ -289,6 +289,12 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) OMV_LCD_BL_TIM_CLK_ENABLE(); } #endif + + #if defined(OMV_BUZZER_TIM) + if (htim->Instance == OMV_BUZZER_TIM) { + OMV_BUZZER_TIM_CLK_ENABLE(); + } + #endif } void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) @@ -300,6 +306,14 @@ void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) OMV_LCD_BL_TIM_CLK_DISABLE(); } #endif + + #if defined(OMV_BUZZER_TIM) + if (htim->Instance == OMV_BUZZER_TIM) { + OMV_BUZZER_TIM_FORCE_RESET(); + OMV_BUZZER_TIM_RELEASE_RESET(); + OMV_BUZZER_TIM_CLK_DISABLE(); + } + #endif } void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)