From 61262435a88aa5683eac403f532fc519dbf4aa07 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Sun, 15 Mar 2026 02:24:58 +0300 Subject: [PATCH] start adding PWM --- F0:F030,F042,F072/usbcan_gpio/gpio.c | 100 +++++++++++++++--- F0:F030,F042,F072/usbcan_gpio/gpio.h | 12 +++ F0:F030,F042,F072/usbcan_gpio/gpioproto.cpp | 24 ++++- F0:F030,F042,F072/usbcan_gpio/pwm.c | 32 ++++++ F0:F030,F042,F072/usbcan_gpio/pwm.h | 21 ++++ F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin | Bin 24296 -> 24872 bytes .../usbcan_gpio/usbcangpio.creator.user | 2 +- .../usbcan_gpio/usbcangpio.files | 2 + F0:F030,F042,F072/usbcan_gpio/version.inc | 4 +- 9 files changed, 175 insertions(+), 22 deletions(-) create mode 100644 F0:F030,F042,F072/usbcan_gpio/pwm.c create mode 100644 F0:F030,F042,F072/usbcan_gpio/pwm.h diff --git a/F0:F030,F042,F072/usbcan_gpio/gpio.c b/F0:F030,F042,F072/usbcan_gpio/gpio.c index ff86226..ad1edf9 100644 --- a/F0:F030,F042,F072/usbcan_gpio/gpio.c +++ b/F0:F030,F042,F072/usbcan_gpio/gpio.c @@ -42,41 +42,93 @@ typedef struct{ #define CANUSART(x) ((x) & (1< need to set up timers / channels +TIM1 / 2 3 +TIM2 / 2 3 4 +TIM3 / 1 2 3 4 +TIM14 / 1 +TIM16 / 1 +#endif + +#define PT(t, ch) {.tim = t, .chidx = ch} +#define PTC(t, ch, P, p) {.tim = t, .chidx = ch, .collision = 1, .collport = P, .collpin = p} +static const pwmtimer_t timer_map[2][16] = { + [0] = { + [1] = PTC(TIM2, 1, 1, 3), + [2] = PTC(TIM2, 2, 1, 10), + [3] = PTC(TIM2, 3, 1, 11), + [6] = PT(TIM16, 0), + [7] = PT(TIM14, 0), + [9] = PT(TIM1, 1), + [10] = PT(TIM1, 2) + }, + [1] = { + [0] = PT(TIM3, 2), + [1] = PT(TIM3, 3), + [3] = PTC(TIM2, 1, 0, 1), + [4] = PT(TIM3, 0), + [5] = PT(TIM3, 1), + [10] = PTC(TIM2, 2, 0, 2), + [11] = PTC(TIM2, 3, 0, 3) + } +}; +#undef PT +#undef PTC typedef struct{ uint8_t isrx : 1; @@ -434,3 +486,17 @@ uint16_t gpio_alert(uint8_t port){ } return alert; } + +/** + * @brief canPWM - check if pin have PWM ability + * @param port - port (0/1 for GPIOA/GPIOB) + * @param pin - pin (0..15) + * @param t (o) - struct for pin's PWM timer + * @return TRUE if can, FALSE if no + */ +int canPWM(uint8_t port, uint8_t pin, pwmtimer_t *t){ + if(port > 1 || pin > 15) return 0; + if(t) *t = timer_map[port][pin]; + if(timer_map[port][pin].tim) return TRUE; + return FALSE; +} diff --git a/F0:F030,F042,F072/usbcan_gpio/gpio.h b/F0:F030,F042,F072/usbcan_gpio/gpio.h index 4d5992d..826471e 100644 --- a/F0:F030,F042,F072/usbcan_gpio/gpio.h +++ b/F0:F030,F042,F072/usbcan_gpio/gpio.h @@ -19,6 +19,7 @@ #pragma once #include +#include #ifdef EBUG #define USBIF IGPIO @@ -90,6 +91,15 @@ typedef struct{ uint16_t threshold; // threshold for ADC measurement } pinconfig_t; +// Timers for PWM +typedef struct{ + volatile TIM_TypeDef *tim; // timer + uint8_t chidx : 2; // channel index (0..3) + uint8_t collision : 1; // have collision with other channel (1) + uint8_t collport : 1; // collision port index (0 - GPIOA, 1 - GPIOB) + uint8_t collpin : 4; // collision pin index (0..15) +} pwmtimer_t; + /* typedef struct{ uint32_t speed; @@ -111,3 +121,5 @@ int gpio_reinit(); int pin_out(uint8_t port, uint8_t pin, uint8_t newval); int16_t pin_in(uint8_t port, uint8_t pin); uint16_t gpio_alert(uint8_t port); + +int canPWM(uint8_t port, uint8_t pin, pwmtimer_t *t); diff --git a/F0:F030,F042,F072/usbcan_gpio/gpioproto.cpp b/F0:F030,F042,F072/usbcan_gpio/gpioproto.cpp index 3b52601..9cde6ca 100644 --- a/F0:F030,F042,F072/usbcan_gpio/gpioproto.cpp +++ b/F0:F030,F042,F072/usbcan_gpio/gpioproto.cpp @@ -54,7 +54,8 @@ static uint8_t hex_input_mode = 0; // ==0 for text input, 1 for HEX + text in qu COMMAND(mcureset, "reset MCU") \ COMMAND(PA, "GPIOA setter/getter (type PA0=help for further info)") \ COMMAND(PB, "GPIOB setter/getter") \ - COMMAND(readconf, "re-read config from flash") \ + COMMAND(pwmmap, "show pins with PWM ability") \ + COMMAND(readconf, "re-read config from flash") \ COMMAND(reinit, "apply pin config") \ COMMAND(saveconf, "save current user configuration into flash") \ COMMAND(sendcan, "send all after '=' to CAN USB interface") \ @@ -679,7 +680,7 @@ static errcodes_t cmd_help(const char _U_ *cmd, char _U_ *args){ return ERR_AMOUNT; } -static errcodes_t cmd_hexinput(const char *cmd, char *args) { +static errcodes_t cmd_hexinput(const char *cmd, char *args){ int32_t val; if(argsvals(args, NULL, &val)){ if(val == 0 || val == 1) hex_input_mode = (uint8_t)val; @@ -690,6 +691,25 @@ static errcodes_t cmd_hexinput(const char *cmd, char *args) { return ERR_AMOUNT; } +static errcodes_t cmd_pwmmap(const char _U_ *cmd, char _U_ *args){ + pwmtimer_t t; + SEND("PWM pins:\n"); + for(int port = 0; port < 2; ++port){ + for(int pin = 0; pin < 16; ++pin){ + if(!canPWM(port, pin, &t)) continue; + SEND((port == 0) ? "PA" : "PB"); + SEND(u2str(pin)); + if(t.collision){ + SEND(" conflicts with "); + SEND((t.collport == 0) ? "PA" : "PB"); + SEND(u2str(t.collpin)); + } + NL(); + } + } + return ERR_AMOUNT; +} + static int sendfun(const char *s){ if(!s) return 0; return USB_sendstr(IGPIO, s); diff --git a/F0:F030,F042,F072/usbcan_gpio/pwm.c b/F0:F030,F042,F072/usbcan_gpio/pwm.c new file mode 100644 index 0000000..4e45470 --- /dev/null +++ b/F0:F030,F042,F072/usbcan_gpio/pwm.c @@ -0,0 +1,32 @@ +/* + * This file is part of the usbcangpio project. + * Copyright 2026 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pwm.h" + +/* + * initial setup of all available PWM timers / channels: + * TIM1 / 2 3 + * TIM2 / 2 3 4 + * TIM3 / 1 2 3 4 + * TIM14 / 1 + * TIM16 / 1 + */ + +void pwm_setup(){ + ; +} diff --git a/F0:F030,F042,F072/usbcan_gpio/pwm.h b/F0:F030,F042,F072/usbcan_gpio/pwm.h new file mode 100644 index 0000000..1a04315 --- /dev/null +++ b/F0:F030,F042,F072/usbcan_gpio/pwm.h @@ -0,0 +1,21 @@ +/* + * This file is part of the usbcangpio project. + * Copyright 2026 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +void pwm_setup(); diff --git a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin index f5500feebd1801f6a4372ac85faffd9cb6ff57c5..25457cc09da79fa5c0b9657bc89d1fda25f8d4ff 100755 GIT binary patch delta 7984 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 - + EnvironmentId diff --git a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.files b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.files index 1df8100..7e44667 100644 --- a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.files +++ b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.files @@ -16,6 +16,8 @@ hashgen/Readme hashgen/hashgen.c hashgen/mktestdic main.c +pwm.c +pwm.h ringbuffer.c ringbuffer.h strfunc.c diff --git a/F0:F030,F042,F072/usbcan_gpio/version.inc b/F0:F030,F042,F072/usbcan_gpio/version.inc index 4d56d69..951c9c1 100644 --- a/F0:F030,F042,F072/usbcan_gpio/version.inc +++ b/F0:F030,F042,F072/usbcan_gpio/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "190" -#define BUILD_DATE "2026-03-14" +#define BUILD_NUMBER "192" +#define BUILD_DATE "2026-03-15"