mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-03-20 00:30:57 +03:00
start adding PWM
This commit is contained in:
@@ -42,41 +42,93 @@ typedef struct{
|
|||||||
#define CANUSART(x) ((x) & (1<<FUNC_USART))
|
#define CANUSART(x) ((x) & (1<<FUNC_USART))
|
||||||
#define CANSPI(x) ((x) & (1<<FUNC_SPI))
|
#define CANSPI(x) ((x) & (1<<FUNC_SPI))
|
||||||
#define CANI2C(x) ((x) & (1<<FUNC_I2C))
|
#define CANI2C(x) ((x) & (1<<FUNC_I2C))
|
||||||
|
#define CANPWM(x) ((x) & (1<<FUNC_PWM))
|
||||||
|
|
||||||
// AF for USART, SPI, I2C:
|
// AF for USART, SPI, I2C:
|
||||||
#define _U(x) [FUNC_USART] = x
|
#define _U(x) [FUNC_USART] = x
|
||||||
// _S(0) or _U(0) have no sence, but lets understand that this pin have SPI or USART
|
// _S(0) or _U(0) have no sence, but lets understand that this pin have SPI or USART
|
||||||
#define _S(x) [FUNC_SPI] = x
|
#define _S(x) [FUNC_SPI] = x
|
||||||
#define _I(x) [FUNC_I2C] = x
|
#define _I(x) [FUNC_I2C] = x
|
||||||
|
#define _P(x) [FUNC_PWM] = x
|
||||||
|
// Here included only common AF for STM32F042 and STM32F072 and without negative timer outputs (stars - collisions)
|
||||||
static const pinprops_t pin_props[2][16] = {
|
static const pinprops_t pin_props[2][16] = {
|
||||||
[0] = { // PORT A
|
[0] = { // PORT A
|
||||||
[0] = { .funcs = 0b00000001, .AF = {0}}, // PA0: ADC0, AF2 (TIM2_CH1)
|
[0] = { .funcs = 0b00000001, .AF = {0}}, // PA0: ADC0
|
||||||
[1] = { .funcs = 0b00000001, .AF = {0}}, // PA1: ADC1, AF2 (TIM2_CH2)
|
[1] = { .funcs = 0b00010001, .AF = {_P(2)}}, // PA1: ADC1, AF2 (TIM2_CH2*)
|
||||||
[2] = { .funcs = 0b00000011, .AF = {_U(1)}}, // PA2: ADC2, AF2 (TIM2_CH3), AF1 (USART2_TX)
|
[2] = { .funcs = 0b00010011, .AF = {_U(1), _P(2)}}, // PA2: ADC2, AF2 (TIM2_CH3**), AF1 (USART2_TX)
|
||||||
[3] = { .funcs = 0b00000011, .AF = {_U(1)}}, // PA3: ADC3, AF2 (TIM2_CH4), AF1 (USART2_RX)
|
[3] = { .funcs = 0b00010011, .AF = {_U(1), _P(2)}}, // PA3: ADC3, AF2 (TIM2_CH4***), AF1 (USART2_RX)
|
||||||
[5] = { .funcs = 0b00000101, .AF = {_S(0)}}, // PA5: ADC5, AF9 (SPI1_SCK)
|
[5] = { .funcs = 0b00000101, .AF = {_S(0)}}, // PA5: ADC5, AF9 (SPI1_SCK)
|
||||||
[6] = { .funcs = 0b00000101, .AF = {_S(0)}}, // PA6: ADC6, AF0 (SPI1_MISO)
|
[6] = { .funcs = 0b00010101, .AF = {_S(0), _P(5)}}, // PA6: ADC6, AF0 (SPI1_MISO), AF5 (TIM16_CH1)
|
||||||
[7] = { .funcs = 0b00000101, .AF = {_S(0)}}, // PA7: ADC7, AF0 (SPI1_MOSI)
|
[7] = { .funcs = 0b00010101, .AF = {_S(0), _P(4)}}, // PA7: ADC7, AF0 (SPI1_MOSI), AF4 (TIM14_CH1)
|
||||||
[9] = { .funcs = 0b00000010, .AF = {_U(1)}}, // PA9: AF1 (USART1_TX)
|
[9] = { .funcs = 0b00010010, .AF = {_U(1), _P(2)}}, // PA9: AF1 (USART1_TX), AF2 (TIM1_CH2)
|
||||||
[10] = { .funcs = 0b00000010, .AF = {_U(1)}}, // PA10: AF1 (USART1_RX)
|
[10] = { .funcs = 0b00010010, .AF = {_U(1), _P(2)}}, // PA10: AF1 (USART1_RX), AF2 (TIM1_CH3)
|
||||||
},
|
},
|
||||||
[1] = { // PORT B
|
[1] = { // PORT B
|
||||||
[0] = { .funcs = 0b00000001, .AF = {0}}, // PB0: ADC8, AF1 (TIM3_CH3), AF2 (TIM1_CH2N)
|
[0] = { .funcs = 0b00010001, .AF = {_P(1)}}, // PB0: ADC8, AF1 (TIM3_CH3)
|
||||||
[1] = { .funcs = 0b00000001, .AF = {0}}, // PB1: ADC9, AF0 (TIM14_CH1), AF1 (TIM3_CH4), AF2 (TIM1_CH3N)
|
[1] = { .funcs = 0b00010001, .AF = {_P(1)}}, // PB1: ADC9, AF1 (TIM3_CH4)
|
||||||
[2] = { .funcs = 0b00000000, .AF = {0}}, // PB2: nothing except GPIO
|
[2] = { .funcs = 0b00000000, .AF = {0}}, // PB2: nothing except GPIO
|
||||||
[3] = { .funcs = 0b00000100, .AF = {_S(0)}}, // PB3: AF0, (SPI1_SCK), AF2 (TIM2_CH2)
|
[3] = { .funcs = 0b00010100, .AF = {_S(0), _P(2)}}, // PB3: AF0, (SPI1_SCK), AF2 (TIM2_CH2*)
|
||||||
[4] = { .funcs = 0b00000100, .AF = {_S(0)}}, // PB4: AF0 (SPI1_MISO), AF1 (TIM3_CH1)
|
[4] = { .funcs = 0b00010100, .AF = {_S(0), _P(1)}}, // PB4: AF0 (SPI1_MISO), AF1 (TIM3_CH1)
|
||||||
[5] = { .funcs = 0b00000100, .AF = {_S(0)}}, // PB5: AF0 (SPI1_MOSI), AF1 (TIM3_CH2)
|
[5] = { .funcs = 0b00010100, .AF = {_S(0), _P(1)}}, // PB5: AF0 (SPI1_MOSI), AF1 (TIM3_CH2)
|
||||||
[6] = { .funcs = 0b00001010, .AF = {_U(0), _I(1)}}, // PB6: AF0 (USART1_TX), AF1 (I2C1_SCL), AF2 (TIM16_CH1N)
|
[6] = { .funcs = 0b00001010, .AF = {_U(0), _I(1)}}, // PB6: AF0 (USART1_TX), AF1 (I2C1_SCL)
|
||||||
[7] = { .funcs = 0b00001010, .AF = {_U(0), _I(1)}}, // PB7: AF0 (USART1_RX), AF1 (I2C1_SDA), AF2 (TIM17_CH1N)
|
[7] = { .funcs = 0b00001010, .AF = {_U(0), _I(1)}}, // PB7: AF0 (USART1_RX), AF1 (I2C1_SDA)
|
||||||
[10] = { .funcs = 0b00001000, .AF = {_I(1)}}, // PB10: AF1 (I2C1_SCL), AF2 (TIM2_CH3)
|
[10] = { .funcs = 0b00011000, .AF = {_I(1), _P(2)}}, // PB10: AF1 (I2C1_SCL), AF2 (TIM2_CH3**)
|
||||||
[11] = { .funcs = 0b00001000, .AF = {_I(1)}}, // PB11: AF1 (I2C1_SDA), AF2 (TIM2_CH4)
|
[11] = { .funcs = 0b00011000, .AF = {_I(1), _P(2)}}, // PB11: AF1 (I2C1_SDA), AF2 (TIM2_CH4***)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#undef _U
|
#undef _U
|
||||||
#undef _S
|
#undef _S
|
||||||
#undef _I
|
#undef _I
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
PWM (start - collisions):
|
||||||
|
PxN XY (XY: TIMX_CHY)
|
||||||
|
PA1 22 *
|
||||||
|
PA2 23 **
|
||||||
|
PA3 24 ***
|
||||||
|
PA6 161
|
||||||
|
PA7 141
|
||||||
|
PA9 12
|
||||||
|
PA10 13
|
||||||
|
PB0 33
|
||||||
|
PB1 34
|
||||||
|
PB3 22 *
|
||||||
|
PB4 31
|
||||||
|
PB5 32
|
||||||
|
PB10 23 **
|
||||||
|
PB11 24 ***
|
||||||
|
-> 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{
|
typedef struct{
|
||||||
uint8_t isrx : 1;
|
uint8_t isrx : 1;
|
||||||
@@ -434,3 +486,17 @@ uint16_t gpio_alert(uint8_t port){
|
|||||||
}
|
}
|
||||||
return alert;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stm32f0.h>
|
||||||
|
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
#define USBIF IGPIO
|
#define USBIF IGPIO
|
||||||
@@ -90,6 +91,15 @@ typedef struct{
|
|||||||
uint16_t threshold; // threshold for ADC measurement
|
uint16_t threshold; // threshold for ADC measurement
|
||||||
} pinconfig_t;
|
} 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{
|
typedef struct{
|
||||||
uint32_t speed;
|
uint32_t speed;
|
||||||
@@ -111,3 +121,5 @@ int gpio_reinit();
|
|||||||
int pin_out(uint8_t port, uint8_t pin, uint8_t newval);
|
int pin_out(uint8_t port, uint8_t pin, uint8_t newval);
|
||||||
int16_t pin_in(uint8_t port, uint8_t pin);
|
int16_t pin_in(uint8_t port, uint8_t pin);
|
||||||
uint16_t gpio_alert(uint8_t port);
|
uint16_t gpio_alert(uint8_t port);
|
||||||
|
|
||||||
|
int canPWM(uint8_t port, uint8_t pin, pwmtimer_t *t);
|
||||||
|
|||||||
@@ -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(mcureset, "reset MCU") \
|
||||||
COMMAND(PA, "GPIOA setter/getter (type PA0=help for further info)") \
|
COMMAND(PA, "GPIOA setter/getter (type PA0=help for further info)") \
|
||||||
COMMAND(PB, "GPIOB setter/getter") \
|
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(reinit, "apply pin config") \
|
||||||
COMMAND(saveconf, "save current user configuration into flash") \
|
COMMAND(saveconf, "save current user configuration into flash") \
|
||||||
COMMAND(sendcan, "send all after '=' to CAN USB interface") \
|
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;
|
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;
|
int32_t val;
|
||||||
if(argsvals(args, NULL, &val)){
|
if(argsvals(args, NULL, &val)){
|
||||||
if(val == 0 || val == 1) hex_input_mode = (uint8_t)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;
|
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){
|
static int sendfun(const char *s){
|
||||||
if(!s) return 0;
|
if(!s) return 0;
|
||||||
return USB_sendstr(IGPIO, s);
|
return USB_sendstr(IGPIO, s);
|
||||||
|
|||||||
32
F0:F030,F042,F072/usbcan_gpio/pwm.c
Normal file
32
F0:F030,F042,F072/usbcan_gpio/pwm.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the usbcangpio project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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(){
|
||||||
|
;
|
||||||
|
}
|
||||||
21
F0:F030,F042,F072/usbcan_gpio/pwm.h
Normal file
21
F0:F030,F042,F072/usbcan_gpio/pwm.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the usbcangpio project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void pwm_setup();
|
||||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 18.0.2, 2026-03-14T01:13:52. -->
|
<!-- Written by QtCreator 18.0.2, 2026-03-15T02:24:04. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ hashgen/Readme
|
|||||||
hashgen/hashgen.c
|
hashgen/hashgen.c
|
||||||
hashgen/mktestdic
|
hashgen/mktestdic
|
||||||
main.c
|
main.c
|
||||||
|
pwm.c
|
||||||
|
pwm.h
|
||||||
ringbuffer.c
|
ringbuffer.c
|
||||||
ringbuffer.h
|
ringbuffer.h
|
||||||
strfunc.c
|
strfunc.c
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "190"
|
#define BUILD_NUMBER "192"
|
||||||
#define BUILD_DATE "2026-03-14"
|
#define BUILD_DATE "2026-03-15"
|
||||||
|
|||||||
Reference in New Issue
Block a user