From 37fc47a24fc9ac0ad670b715fe99aa2516446b6b Mon Sep 17 00:00:00 2001 From: DrZlo13 Date: Fri, 23 Oct 2020 12:39:11 +0300 Subject: [PATCH] IR transmit example (#180) * DWT-based microsecond delay * simple ir app (work only with NEC protocol and predefined address - command) * remove space from file name, add delay_us_init_DWT header * float-based delay us * init tim2 by CubeMX * fix simple pwm functions * simple pwm timer based ir nec protocol * ir gui test app Co-authored-by: aanper --- applications/applications.h | 8 + applications/applications.mk | 14 ++ applications/irda/irda.c | 238 +++++++++++++++++++++++++ applications/irda/irda_nec.c | 46 +++++ applications/irda/irda_nec.h | 4 + applications/irda/irda_protocols.h | 16 ++ firmware/targets/f2/Inc/flipper_hal.h | 5 +- firmware/targets/f2/Inc/tim.h | 2 + firmware/targets/f2/Makefile | 58 +++++- firmware/targets/f2/Src/flipper_hal.c | 23 ++- firmware/targets/f2/Src/gpio.c | 6 +- firmware/targets/f2/Src/main.c | 3 + firmware/targets/f2/Src/stm32l4xx_it.c | 6 +- firmware/targets/f2/Src/tim.c | 157 ++++++++++++---- 14 files changed, 531 insertions(+), 55 deletions(-) create mode 100644 applications/irda/irda.c create mode 100644 applications/irda/irda_nec.c create mode 100644 applications/irda/irda_nec.h create mode 100644 applications/irda/irda_protocols.h diff --git a/applications/applications.h b/applications/applications.h index 5a1b52c6..7de48699 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -25,6 +25,7 @@ void u8g2_qrcode(void* p); void fatfs_list(void* p); void gui_task(void* p); void backlight_control(void* p); +void irda(void* p); void app_loader(void* p); void cc1101_workaround(void* p); void nfc_task(void* p); @@ -52,6 +53,10 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { {.app = cc1101_workaround, .name = "cc1101 workaround", .libs = {1, FURI_LIB{"gui_task"}}}, #endif +#ifdef APP_IRDA + {.app = irda, .name = "irda", .libs = {1, FURI_LIB{"gui_task"}}}, +#endif + #ifdef APP_NFC {.app = nfc_task, .name = "nfc_task", .libs = {1, FURI_LIB{"menu_task"}}}, #endif @@ -96,4 +101,7 @@ const FlipperStartupApp FLIPPER_APPS[] = { #ifdef BUILD_CC1101 {.app = cc1101_workaround, .name = "cc1101 workaround", .libs = {1, FURI_LIB{"gui_task"}}}, #endif +#ifdef BUILD_IRDA + {.app = irda, .name = "irda", .libs = {1, FURI_LIB{"gui_task"}}}, +#endif }; \ No newline at end of file diff --git a/applications/applications.mk b/applications/applications.mk index b57cff23..6dc0baf9 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -10,6 +10,7 @@ APP_RELEASE ?= 0 ifeq ($(APP_RELEASE), 1) APP_MENU = 1 APP_NFC = 1 +BUILD_IRDA = 1 BUILD_EXAMPLE_BLINK = 1 BUILD_EXAMPLE_UART_WRITE = 1 BUILD_EXAMPLE_INPUT_DUMP = 1 @@ -142,6 +143,19 @@ APP_INPUT = 1 APP_GUI = 1 endif +APP_IRDA?= 0 +ifeq ($(APP_IRDA), 1) +CFLAGS += -DAPP_IRDA +BUILD_IRDA = 1 +endif +BUILD_IRDA ?= 0 +ifeq ($(BUILD_IRDA), 1) +CFLAGS += -DBUILD_IRDA +C_SOURCES += $(wildcard $(APP_DIR)/irda/*.c) +APP_INPUT = 1 +APP_GUI = 1 +endif + # device drivers APP_GUI ?= 0 diff --git a/applications/irda/irda.c b/applications/irda/irda.c new file mode 100644 index 00000000..9aa5a3d1 --- /dev/null +++ b/applications/irda/irda.c @@ -0,0 +1,238 @@ +#include "flipper.h" +#include "flipper_v2.h" +#include "irda_nec.h" +#include "irda_protocols.h" + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + union { + InputEvent input; + } value; + EventType type; +} Event; + +typedef struct { + uint8_t mode_id; + uint16_t carrier_freq; + uint8_t carrier_duty_cycle_id; + uint8_t nec_packet_id; +} State; + +typedef void (*ModeInput)(Event*, State*); +typedef void (*ModeRender)(CanvasApi*, State*); + +void input_carrier(Event* event, State* state); +void render_carrier(CanvasApi* canvas, State* state); +void input_nec(Event* event, State* state); +void render_nec(CanvasApi* canvas, State* state); + +typedef struct { + ModeRender render; + ModeInput input; +} Mode; + +typedef struct { + uint8_t addr; + uint8_t data; +} NecPacket; + +const Mode modes[] = { + {.render = render_carrier, .input = input_carrier}, + {.render = render_nec, .input = input_nec}, +}; + +const NecPacket packets[] = { + {.addr = 0xF7, .data = 0x59}, + {.addr = 0xFF, .data = 0x01}, + {.addr = 0xFF, .data = 0x10}, + {.addr = 0xFF, .data = 0x15}, + {.addr = 0xFF, .data = 0x25}, + {.addr = 0xFF, .data = 0xF0}, +}; + +const float duty_cycles[] = {0.1, 0.25, 0.333, 0.5, 1.0}; + +void render_carrier(CanvasApi* canvas, State* state) { + canvas->set_font(canvas, FontSecondary); + canvas->draw_str(canvas, 2, 25, "carrier mode >"); + canvas->draw_str(canvas, 2, 37, "? /\\ freq | \\/ duty cycle"); + { + char buf[24]; + sprintf(buf, "frequency: %d Hz", state->carrier_freq); + canvas->draw_str(canvas, 2, 50, buf); + sprintf( + buf, + "duty cycle: %d/1000", + (uint32_t)(duty_cycles[state->carrier_duty_cycle_id] * 1000)); + canvas->draw_str(canvas, 2, 62, buf); + } +} + +void render_nec(CanvasApi* canvas, State* state) { + canvas->set_font(canvas, FontSecondary); + canvas->draw_str(canvas, 2, 25, "< nec protocol mode"); + canvas->draw_str(canvas, 2, 37, "? /\\ \\/ packet"); + { + char buf[24]; + sprintf( + buf, + "packet: %02X %02X", + packets[state->nec_packet_id].addr, + packets[state->nec_packet_id].data); + canvas->draw_str(canvas, 2, 50, buf); + } +} + +void input_carrier(Event* event, State* state) { + if(event->value.input.input == InputOk) { + if(event->value.input.state) { + pwm_set( + duty_cycles[state->carrier_duty_cycle_id], + state->carrier_freq, + &htim2, + TIM_CHANNEL_4); + } else { + pwm_stop(&htim2, TIM_CHANNEL_4); + } + } + + if(event->value.input.state && event->value.input.input == InputUp) { + if(state->carrier_freq < 45000) { + state->carrier_freq += 1000; + } else { + state->carrier_freq = 33000; + } + } + + if(event->value.input.state && event->value.input.input == InputDown) { + uint8_t duty_cycles_count = sizeof(duty_cycles) / sizeof(duty_cycles[0]); + if(state->carrier_duty_cycle_id < (duty_cycles_count - 1)) { + state->carrier_duty_cycle_id++; + } else { + state->carrier_duty_cycle_id = 0; + } + } +} + +void input_nec(Event* event, State* state) { + if(event->value.input.input == InputOk) { + if(event->value.input.state) { + vTaskSuspendAll(); + ir_nec_send(packets[state->nec_packet_id].addr, packets[state->nec_packet_id].data); + xTaskResumeAll(); + } + } + + if(event->value.input.state && event->value.input.input == InputUp) { + uint8_t packets_count = sizeof(packets) / sizeof(packets[0]); + if(state->nec_packet_id < (packets_count - 1)) { + state->nec_packet_id++; + } else { + state->nec_packet_id = 0; + } + } + + if(event->value.input.state && event->value.input.input == InputDown) { + uint8_t packets_count = sizeof(packets) / sizeof(packets[0]); + if(state->nec_packet_id > 0) { + state->nec_packet_id--; + } else { + state->nec_packet_id = packets_count - 1; + } + } +} + +static void render_callback(CanvasApi* canvas, void* ctx) { + State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); + + canvas->clear(canvas); + canvas->set_color(canvas, ColorBlack); + canvas->set_font(canvas, FontPrimary); + canvas->draw_str(canvas, 2, 12, "irda test"); + + modes[state->mode_id].render(canvas, state); + + release_mutex((ValueMutex*)ctx, state); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + osMessageQueueId_t event_queue = (QueueHandle_t)ctx; + + Event event; + event.type = EventTypeKey; + event.value.input = *input_event; + osMessageQueuePut(event_queue, &event, 0, 0); +} + +void irda(void* p) { + osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(Event), NULL); + + State _state; + uint8_t mode_count = sizeof(modes) / sizeof(modes[0]); + uint8_t duty_cycles_count = sizeof(duty_cycles) / sizeof(duty_cycles[0]); + + _state.carrier_duty_cycle_id = duty_cycles_count - 2; + _state.carrier_freq = 36000; + _state.mode_id = 0; + _state.nec_packet_id = 0; + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, &_state, sizeof(State))) { + printf("cannot create mutex\n"); + furiac_exit(NULL); + } + + Widget* widget = widget_alloc(); + + widget_draw_callback_set(widget, render_callback, &state_mutex); + widget_input_callback_set(widget, input_callback, event_queue); + + // Open GUI and register widget + GuiApi* gui = (GuiApi*)furi_open("gui"); + if(gui == NULL) { + printf("gui is not available\n"); + furiac_exit(NULL); + } + gui->add_widget(gui, widget, WidgetLayerFullscreen); + + Event event; + while(1) { + osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); + State* state = (State*)acquire_mutex_block(&state_mutex); + + if(event_status == osOK) { + if(event.type == EventTypeKey) { + // press events + if(event.value.input.state && event.value.input.input == InputBack) { + printf("[irda] bye!\n"); + // TODO remove all widgets create by app + widget_enabled_set(widget, false); + furiac_exit(NULL); + } + + if(event.value.input.state && event.value.input.input == InputLeft) { + if(state->mode_id > 0) { + state->mode_id--; + } + } + + if(event.value.input.state && event.value.input.input == InputRight) { + if(state->mode_id < (mode_count - 1)) { + state->mode_id++; + } + } + + modes[state->mode_id].input(&event, state); + } + } else { + // event timeout + } + + release_mutex(&state_mutex, state); + widget_update(widget); + } +} \ No newline at end of file diff --git a/applications/irda/irda_nec.c b/applications/irda/irda_nec.c new file mode 100644 index 00000000..683fbb8f --- /dev/null +++ b/applications/irda/irda_nec.c @@ -0,0 +1,46 @@ +#include "flipper.h" +#include "irda_nec.h" +#include "irda_protocols.h" + +void ir_nec_preambula(void) { + // 9ms carrier + 4.5ms pause + pwm_set(NEC_DUTY_CYCLE, NEC_CARRIER_FREQUENCY, &htim2, TIM_CHANNEL_4); + delay_us(9000); + pwm_stop(&htim2, TIM_CHANNEL_4); + delay_us(4500); +} + +void ir_nec_send_bit(bool bit) { + // 0 is 562.5us carrier + 1687.5us pause + // 1 is 562.5us carrier + 562.5us pause + pwm_set(NEC_DUTY_CYCLE, NEC_CARRIER_FREQUENCY, &htim2, TIM_CHANNEL_4); + delay_us(562.5); + pwm_stop(&htim2, TIM_CHANNEL_4); + if(bit) { + delay_us(562.5); + } else { + delay_us(1687.5); + } +} + +void ir_nec_send_byte(uint8_t data) { + for(uint8_t i = 0; i < 8; i++) { + ir_nec_send_bit((data & (1 << (i))) != 0); + } +} + +void ir_nec_send(uint8_t addr, uint8_t data) { + // nec protocol is: + // preambula + addr + inverse addr + command + inverse command + bit pulse + // + // oddly enough, my analyzer (https://github.com/ukw100/IRMP) displays the reverse command + // and I don’t know if this is my fault or a feature of the analyzer + // TODO: check the dictionary and check with a known remote + uint8_t nec_packet[4] = {addr, ~(uint8_t)addr, ~(uint8_t)data, data}; + ir_nec_preambula(); + ir_nec_send_byte(nec_packet[0]); + ir_nec_send_byte(nec_packet[1]); + ir_nec_send_byte(nec_packet[2]); + ir_nec_send_byte(nec_packet[3]); + ir_nec_send_bit(1); +} \ No newline at end of file diff --git a/applications/irda/irda_nec.h b/applications/irda/irda_nec.h new file mode 100644 index 00000000..5bd18bde --- /dev/null +++ b/applications/irda/irda_nec.h @@ -0,0 +1,4 @@ +#pragma once +#include "flipper.h" + +void ir_nec_send(uint8_t addr, uint8_t data); \ No newline at end of file diff --git a/applications/irda/irda_protocols.h b/applications/irda/irda_protocols.h new file mode 100644 index 00000000..5260e689 --- /dev/null +++ b/applications/irda/irda_protocols.h @@ -0,0 +1,16 @@ +#pragma once + +// our tx pin is TIM2_CH4 +extern TIM_HandleTypeDef htim2; + +#define RC5_CARRIER_FREQUENCY 36000 +#define RC5_DUTY_CYCLE 0.33 + +#define RC6_CARRIER_FREQUENCY 36000 +#define RC6_DUTY_CYCLE 0.33 + +#define NEC_CARRIER_FREQUENCY 38000 +#define NEC_DUTY_CYCLE 0.33 + +#define SIRC_CARRIER_FREQUENCY 40000 +#define SIRC_DUTY_CYCLE 0.5 \ No newline at end of file diff --git a/firmware/targets/f2/Inc/flipper_hal.h b/firmware/targets/f2/Inc/flipper_hal.h index 628674ce..9e12a237 100644 --- a/firmware/targets/f2/Inc/flipper_hal.h +++ b/firmware/targets/f2/Inc/flipper_hal.h @@ -35,10 +35,11 @@ static inline bool app_gpio_read(GpioPin gpio) { return false; } - -void delay_us(uint32_t time); +void delay_us_init_DWT(void); +void delay_us(float time); void pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel); +void pwm_stop(TIM_HandleTypeDef* tim, uint32_t channel); extern TIM_HandleTypeDef htim8; diff --git a/firmware/targets/f2/Inc/tim.h b/firmware/targets/f2/Inc/tim.h index 46b53f5d..ee837a1a 100644 --- a/firmware/targets/f2/Inc/tim.h +++ b/firmware/targets/f2/Inc/tim.h @@ -30,6 +30,7 @@ /* USER CODE END Includes */ +extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim5; extern TIM_HandleTypeDef htim8; extern TIM_HandleTypeDef htim15; @@ -38,6 +39,7 @@ extern TIM_HandleTypeDef htim15; /* USER CODE END Private defines */ +void MX_TIM2_Init(void); void MX_TIM5_Init(void); void MX_TIM8_Init(void); void MX_TIM15_Init(void); diff --git a/firmware/targets/f2/Makefile b/firmware/targets/f2/Makefile index 753f352b..e0bc903b 100644 --- a/firmware/targets/f2/Makefile +++ b/firmware/targets/f2/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.10.0-B14] date: [Fri Oct 02 17:54:23 MSK 2020] +# File automatically-generated by tool: [projectgenerator] version: [3.10.0-B14] date: [Wed Oct 21 03:57:12 VLAT 2020] ########################################################################################################################## # ------------------------------------------------ @@ -92,7 +92,48 @@ Src/system_stm32l4xx.c \ /Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ /Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c \ /Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ -Src/stm32l4xx_hal_timebase_tim.c +Src/stm32l4xx_hal_timebase_tim.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_comp.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/list.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ +C:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c # ASM sources ASM_SOURCES = \ @@ -159,8 +200,17 @@ C_INCLUDES = \ -I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ -I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ -I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Device/ST/STM32L4xx/Include \ --I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Include --I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Include +-I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Include \ +-I/Users/aku/Work/flipper/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Include \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Inc \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/STM32L4xx_HAL_Driver/Inc/Legacy \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/include \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Device/ST/STM32L4xx/Include \ +-IC:/work/cmake-stm32/projects/flipperzero-firmware-community/lib/STM32CubeL4/Drivers/CMSIS/Include # compile gcc flags diff --git a/firmware/targets/f2/Src/flipper_hal.c b/firmware/targets/f2/Src/flipper_hal.c index ba9f4673..04264b20 100644 --- a/firmware/targets/f2/Src/flipper_hal.c +++ b/firmware/targets/f2/Src/flipper_hal.c @@ -34,17 +34,22 @@ void app_gpio_init(GpioPin gpio, GpioMode mode) { } } -// TODO delay from timer -void delay_us(uint32_t time) { - time *= 11.8; +void delay_us_init_DWT(void) { + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + DWT->CYCCNT = 0U; +} - while(time--) { - } +void delay_us(float time) { + uint32_t start = DWT->CYCCNT; + uint32_t time_ticks = time * (SystemCoreClock / 1000000); + while((DWT->CYCCNT - start) < time_ticks) { + }; } void pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) { tim->Init.CounterMode = TIM_COUNTERMODE_UP; - tim->Init.Period = (uint32_t)((SystemCoreClock / tim->Init.Prescaler) / freq); + tim->Init.Period = (uint32_t)((SystemCoreClock / (tim->Init.Prescaler + 1)) / freq); tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; HAL_TIM_PWM_Init(tim); @@ -52,9 +57,13 @@ void pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = (uint16_t)(291 * value); + sConfigOC.Pulse = (uint16_t)(tim->Init.Period * value); sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(tim, &sConfigOC, channel); HAL_TIM_PWM_Start(tim, channel); +} + +void pwm_stop(TIM_HandleTypeDef* tim, uint32_t channel) { + HAL_TIM_PWM_Stop(tim, channel); } \ No newline at end of file diff --git a/firmware/targets/f2/Src/gpio.c b/firmware/targets/f2/Src/gpio.c index a9491254..5ecf12ec 100644 --- a/firmware/targets/f2/Src/gpio.c +++ b/firmware/targets/f2/Src/gpio.c @@ -59,7 +59,7 @@ void MX_GPIO_Init(void) HAL_GPIO_WritePin(GPIOB, LED_BLUE_Pin|LED_GREEN_Pin, GPIO_PIN_SET); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOB, DISPLAY_RST_Pin|IR_TX_Pin|DISPLAY_BACKLIGHT_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, DISPLAY_RST_Pin|DISPLAY_BACKLIGHT_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, VIBRO_Pin|DISPLAY_CS_Pin, GPIO_PIN_RESET); @@ -130,8 +130,8 @@ void MX_GPIO_Init(void) GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - /*Configure GPIO pins : PBPin PBPin PBPin */ - GPIO_InitStruct.Pin = DISPLAY_RST_Pin|IR_TX_Pin|DISPLAY_BACKLIGHT_Pin; + /*Configure GPIO pins : PBPin PBPin */ + GPIO_InitStruct.Pin = DISPLAY_RST_Pin|DISPLAY_BACKLIGHT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; diff --git a/firmware/targets/f2/Src/main.c b/firmware/targets/f2/Src/main.c index cea4cf34..87b31489 100644 --- a/firmware/targets/f2/Src/main.c +++ b/firmware/targets/f2/Src/main.c @@ -31,6 +31,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "fatfs/fatfs.h" +#include "flipper_hal.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -100,8 +101,10 @@ int main(void) MX_TIM15_Init(); MX_USART1_UART_Init(); MX_TIM8_Init(); + MX_TIM2_Init(); /* USER CODE BEGIN 2 */ MX_FATFS_Init(); + delay_us_init_DWT(); /* USER CODE END 2 */ /* Init scheduler */ diff --git a/firmware/targets/f2/Src/stm32l4xx_it.c b/firmware/targets/f2/Src/stm32l4xx_it.c index 3cd3363d..5d4e13f9 100644 --- a/firmware/targets/f2/Src/stm32l4xx_it.c +++ b/firmware/targets/f2/Src/stm32l4xx_it.c @@ -239,9 +239,8 @@ void EXTI9_5_IRQHandler(void) void TIM1_TRG_COM_TIM17_IRQHandler(void) { /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */ - - /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ HAL_TIM_IRQHandler(&htim17); + /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */ /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */ @@ -282,9 +281,8 @@ void TIM8_CC_IRQHandler(void) void OTG_FS_IRQHandler(void) { /* USER CODE BEGIN OTG_FS_IRQn 0 */ - - /* USER CODE END OTG_FS_IRQn 0 */ HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + /* USER CODE END OTG_FS_IRQn 0 */ /* USER CODE BEGIN OTG_FS_IRQn 1 */ /* USER CODE END OTG_FS_IRQn 1 */ diff --git a/firmware/targets/f2/Src/tim.c b/firmware/targets/f2/Src/tim.c index 2b554234..c54c22e9 100644 --- a/firmware/targets/f2/Src/tim.c +++ b/firmware/targets/f2/Src/tim.c @@ -24,10 +24,54 @@ /* USER CODE END 0 */ +TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim5; TIM_HandleTypeDef htim8; TIM_HandleTypeDef htim15; +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + htim2.Instance = TIM2; + htim2.Init.Prescaler = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 1684; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 842; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + HAL_TIM_MspPostInit(&htim2); + +} /* TIM5 init function */ void MX_TIM5_Init(void) { @@ -155,27 +199,22 @@ void MX_TIM15_Init(void) } -void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) -{ - - if(tim_pwmHandle->Instance==TIM5) - { - /* USER CODE BEGIN TIM5_MspInit 0 */ - - /* USER CODE END TIM5_MspInit 0 */ - /* TIM5 clock enable */ - __HAL_RCC_TIM5_CLK_ENABLE(); - /* USER CODE BEGIN TIM5_MspInit 1 */ - - /* USER CODE END TIM5_MspInit 1 */ - } -} - void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(tim_baseHandle->Instance==TIM8) + if(tim_baseHandle->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspInit 0 */ + + /* USER CODE END TIM2_MspInit 0 */ + /* TIM2 clock enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + /* USER CODE BEGIN TIM2_MspInit 1 */ + + /* USER CODE END TIM2_MspInit 1 */ + } + else if(tim_baseHandle->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspInit 0 */ @@ -203,6 +242,22 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) } } +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) +{ + + if(tim_pwmHandle->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspInit 0 */ + + /* USER CODE END TIM5_MspInit 0 */ + /* TIM5 clock enable */ + __HAL_RCC_TIM5_CLK_ENABLE(); + /* USER CODE BEGIN TIM5_MspInit 1 */ + + /* USER CODE END TIM5_MspInit 1 */ + } +} + void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* tim_ocHandle) { @@ -222,11 +277,32 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(timHandle->Instance==TIM5) + if(timHandle->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspPostInit 0 */ + + /* USER CODE END TIM2_MspPostInit 0 */ + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**TIM2 GPIO Configuration + PB11 ------> TIM2_CH4 + */ + GPIO_InitStruct.Pin = IR_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(IR_TX_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM2_MspPostInit 1 */ + + /* USER CODE END TIM2_MspPostInit 1 */ + } + else if(timHandle->Instance==TIM5) { /* USER CODE BEGIN TIM5_MspPostInit 0 */ /* USER CODE END TIM5_MspPostInit 0 */ + __HAL_RCC_GPIOA_CLK_ENABLE(); /**TIM5 GPIO Configuration PA3 ------> TIM5_CH4 @@ -266,26 +342,21 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) } -void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle) -{ - - if(tim_pwmHandle->Instance==TIM5) - { - /* USER CODE BEGIN TIM5_MspDeInit 0 */ - - /* USER CODE END TIM5_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM5_CLK_DISABLE(); - /* USER CODE BEGIN TIM5_MspDeInit 1 */ - - /* USER CODE END TIM5_MspDeInit 1 */ - } -} - void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) { - if(tim_baseHandle->Instance==TIM8) + if(tim_baseHandle->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspDeInit 0 */ + + /* USER CODE END TIM2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM2_CLK_DISABLE(); + /* USER CODE BEGIN TIM2_MspDeInit 1 */ + + /* USER CODE END TIM2_MspDeInit 1 */ + } + else if(tim_baseHandle->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspDeInit 0 */ @@ -306,6 +377,22 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) } } +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle) +{ + + if(tim_pwmHandle->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspDeInit 0 */ + + /* USER CODE END TIM5_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM5_CLK_DISABLE(); + /* USER CODE BEGIN TIM5_MspDeInit 1 */ + + /* USER CODE END TIM5_MspDeInit 1 */ + } +} + void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef* tim_ocHandle) {