STM32F411: Allow non-PWM pins as heater output.

This commit is contained in:
Nico Tonnhofer 2016-03-24 22:24:24 +01:00
parent 423c5694d0
commit afc4c3e8e4
2 changed files with 229 additions and 72 deletions

View File

@ -34,6 +34,8 @@
Use alphas for PORT and numerics for PIN, close to the design.
*/
#define NO_TIMER ((TIM_TypeDef *) 0)
#define PA_0_PIN 0
#define PA_0_PORT GPIOA
#define PA_0_ADC 0
@ -52,6 +54,10 @@
#define PA_2_PIN 2
#define PA_2_PORT GPIOA
#define PA_2_AF 0
#define PA_2_TIMER NO_TIMER
#define PA_2_CHANNEL 1
#define PA_2_INVERT 0
// #define PA_2_ADC 2
// #define PA_2_AF 3
// #define PA_2_TIMER TIM9
@ -60,6 +66,10 @@
#define PA_3_PIN 3
#define PA_3_PORT GPIOA
#define PA_3_AF 0
#define PA_3_TIMER NO_TIMER
#define PA_3_CHANNEL 1
#define PA_3_INVERT 0
// #define PA_3_ADC 3
// #define PA_3_AF 3
// #define PA_3_TIMER TIM9
@ -69,6 +79,10 @@
#define PA_4_PIN 4
#define PA_4_PORT GPIOA
#define PA_4_ADC 4
#define PA_4_AF 0
#define PA_4_TIMER NO_TIMER
#define PA_4_CHANNEL 1
#define PA_4_INVERT 0
#define PA_5_PIN 5
#define PA_5_PORT GPIOA
@ -81,6 +95,10 @@
#define PA_6_PIN 6
#define PA_6_PORT GPIOA
#define PA_6_ADC 6
#define PA_6_AF 0
#define PA_6_TIMER NO_TIMER
#define PA_6_CHANNEL 1
#define PA_6_INVERT 0
// #define PA_6_AF 2
// #define PA_6_TIMER TIM3
// #define PA_6_CHANNEL 1
@ -89,6 +107,10 @@
#define PA_7_PIN 7
#define PA_7_PORT GPIOA
#define PA_7_ADC 7
#define PA_7_AF 0
#define PA_7_TIMER NO_TIMER
#define PA_7_CHANNEL 1
#define PA_7_INVERT 0
// #define PA_7_AF 1
// #define PA_7_TIMER TIM1
// #define PA_7_CHANNEL 1
@ -124,15 +146,31 @@
#define PA_12_PIN 12
#define PA_12_PORT GPIOA
#define PA_12_AF 0
#define PA_12_TIMER NO_TIMER
#define PA_12_CHANNEL 0
#define PA_12_INVERT 0
#define PA_13_PIN 13
#define PA_13_PORT GPIOA
#define PA_13_AF 0
#define PA_13_TIMER NO_TIMER
#define PA_13_CHANNEL 0
#define PA_13_INVERT 0
#define PA_14_PIN 14
#define PA_14_PORT GPIOA
#define PA_14_AF 0
#define PA_14_TIMER NO_TIMER
#define PA_14_CHANNEL 0
#define PA_14_INVERT 0
#define PA_15_PIN 15
#define PA_15_PORT GPIOA
#define PA_15_AF 0
#define PA_15_TIMER NO_TIMER
#define PA_15_CHANNEL 0
#define PA_15_INVERT 0
// #define PA_15_AF 1
// #define PA_15_TIMER TIM2
// #define PA_15_CHANNEL 1
@ -156,9 +194,17 @@
#define PB_2_PIN 2
#define PB_2_PORT GPIOB
#define PB_2_AF 0
#define PB_2_TIMER NO_TIMER
#define PB_2_CHANNEL 1
#define PB_2_INVERT 0
#define PB_3_PIN 3
#define PB_3_PORT GPIOB
#define PB_3_AF 0
#define PB_3_TIMER NO_TIMER
#define PB_3_CHANNEL 1
#define PB_3_INVERT 0
// #define PB_3_AF 1
// #define PB_3_TIMER TIM2
// #define PB_3_CHANNEL 2
@ -215,9 +261,17 @@
#define PB_12_PIN 12
#define PB_12_PORT GPIOB
#define PB_12_AF 0
#define PB_12_TIMER NO_TIMER
#define PB_12_CHANNEL 0
#define PB_12_INVERT 0
#define PB_13_PIN 13
#define PB_13_PORT GPIOB
#define PB_13_AF 0
#define PB_13_TIMER NO_TIMER
#define PB_13_CHANNEL 0
#define PB_13_INVERT 0
// #define PB_13_AF 1
// #define PB_13_TIMER TIM1
// #define PB_13_CHANNEL 1
@ -225,6 +279,10 @@
#define PB_14_PIN 14
#define PB_14_PORT GPIOB
#define PB_14_AF 0
#define PB_14_TIMER NO_TIMER
#define PB_14_CHANNEL 0
#define PB_14_INVERT 0
// #define PB_14_AF 1
// #define PB_14_TIMER TIM1
// #define PB_14_CHANNEL 2
@ -232,6 +290,10 @@
#define PB_15_PIN 15
#define PB_15_PORT GPIOB
#define PB_15_AF 0
#define PB_15_TIMER NO_TIMER
#define PB_15_CHANNEL 0
#define PB_15_INVERT 0
// #define PB_15_AF 1
// #define PB_15_TIMER TIM1
// #define PB_15_CHANNEL 3
@ -240,29 +302,57 @@
#define PC_0_PIN 0
#define PC_0_PORT GPIOC
#define PC_0_ADC 10
#define PC_0_AF 0
#define PC_0_TIMER NO_TIMER
#define PC_0_CHANNEL 1
#define PC_0_INVERT 0
#define PC_1_PIN 1
#define PC_1_PORT GPIOC
#define PC_1_ADC 11
#define PC_1_AF 0
#define PC_1_TIMER NO_TIMER
#define PC_1_CHANNEL 1
#define PC_1_INVERT 0
#define PC_2_PIN 2
#define PC_2_PORT GPIOC
#define PC_2_ADC 12
#define PC_2_AF 0
#define PC_2_TIMER NO_TIMER
#define PC_2_CHANNEL 1
#define PC_2_INVERT 0
#define PC_3_PIN 3
#define PC_3_PORT GPIOC
#define PC_3_ADC 13
#define PC_3_AF 0
#define PC_3_TIMER NO_TIMER
#define PC_3_CHANNEL 1
#define PC_3_INVERT 0
#define PC_4_PIN 4
#define PC_4_PORT GPIOC
#define PC_4_ADC 14
#define PC_4_AF 0
#define PC_4_TIMER NO_TIMER
#define PC_4_CHANNEL 1
#define PC_4_INVERT 0
#define PC_5_PIN 5
#define PC_5_PORT GPIOC
#define PC_5_ADC 15
#define PC_5_AF 0
#define PC_5_TIMER NO_TIMER
#define PC_5_CHANNEL 1
#define PC_5_INVERT 0
#define PC_6_PIN 6
#define PC_6_PORT GPIOC
#define PC_6_AF 0
#define PC_6_TIMER NO_TIMER
#define PC_6_CHANNEL 1
#define PC_6_INVERT 0
// #define PC_6_AF 2
// #define PC_6_TIMER TIM3
// #define PC_6_CHANNEL 1
@ -270,6 +360,10 @@
#define PC_7_PIN 7
#define PC_7_PORT GPIOC
#define PC_7_AF 0
#define PC_7_TIMER NO_TIMER
#define PC_7_CHANNEL 1
#define PC_7_INVERT 0
// #define PC_7_AF 2
// #define PC_7_TIMER TIM3
// #define PC_7_CHANNEL 2
@ -277,6 +371,10 @@
#define PC_8_PIN 8
#define PC_8_PORT GPIOC
#define PC_8_AF 0
#define PC_8_TIMER NO_TIMER
#define PC_8_CHANNEL 1
#define PC_8_INVERT 0
// #define PC_8_AF 2
// #define PC_8_TIMER TIM3
// #define PC_8_CHANNEL 3
@ -284,6 +382,10 @@
#define PC_9_PIN 9
#define PC_9_PORT GPIOC
#define PC_9_AF 0
#define PC_9_TIMER NO_TIMER
#define PC_9_CHANNEL 1
#define PC_9_INVERT 0
// #define PC_9_AF 2
// #define PC_9_TIMER TIM3
// #define PC_9_CHANNEL 4
@ -291,27 +393,63 @@
#define PC_10_PIN 10
#define PC_10_PORT GPIOC
#define PC_10_AF 0
#define PC_10_TIMER NO_TIMER
#define PC_10_CHANNEL 0
#define PC_10_INVERT 0
#define PC_11_PIN 11
#define PC_11_PORT GPIOC
#define PC_11_AF 0
#define PC_11_TIMER NO_TIMER
#define PC_11_CHANNEL 0
#define PC_11_INVERT 0
#define PC_12_PIN 12
#define PC_12_PORT GPIOC
#define PC_12_AF 0
#define PC_12_TIMER NO_TIMER
#define PC_12_CHANNEL 1
#define PC_12_INVERT 0
#define PC_13_PIN 13
#define PC_13_PORT GPIOC
#define PC_13_AF 0
#define PC_13_TIMER NO_TIMER
#define PC_13_CHANNEL 1
#define PC_13_INVERT 0
#define PC_14_PIN 14
#define PC_14_PORT GPIOC
#define PC_14_AF 0
#define PC_14_TIMER NO_TIMER
#define PC_14_CHANNEL 1
#define PC_14_INVERT 0
#define PC_15_PIN 15
#define PC_15_PORT GPIOC
#define PC_15_AF 0
#define PC_15_TIMER NO_TIMER
#define PC_15_CHANNEL 1
#define PC_15_INVERT 0
#define PD_2_PIN 2
#define PD_2_PORT GPIOD
#define PD_2_AF 0
#define PD_2_TIMER NO_TIMER
#define PD_2_CHANNEL 1
#define PD_2_INVERT 0
#define PH_0_PIN 0
#define PH_0_PORT GPIOH
#define PH_0_AF 0
#define PH_0_TIMER NO_TIMER
#define PH_0_CHANNEL 1
#define PH_0_INVERT 0
#define PH_1_PIN 1
#define PH_1_PORT GPIOH
#define PH_1_AF 0
#define PH_1_TIMER NO_TIMER
#define PH_1_CHANNEL 1
#define PH_1_INVERT 0

View File

@ -61,13 +61,25 @@
#include "config_wrapper.h" trick.
*/
typedef struct {
union {
/// Pointer to the capture compare register which changes PWM duty.
__IO uint32_t* ccr;
/// Pointer to the port for non-PWM pins.
__IO uint32_t* bsrr;
};
uint16_t masked_pin;
uint8_t uses_pwm;
} heater_definition_t;
#undef DEFINE_HEATER
#define DEFINE_HEATER(name, pin, pwm) \
{ &(pin ## _TIMER-> EXPANDER(CCR, pin ## _CHANNEL,)) },
{ \
{ pwm && pin ## _TIMER ? \
&(pin ## _TIMER-> EXPANDER(CCR, pin ## _CHANNEL,)) : \
&(pin ## _PORT->BSRR) }, \
MASK(pin ## _PIN), \
pwm && pin ## _TIMER \
},
static const heater_definition_t heaters[NUM_HEATERS] = {
#include "config_wrapper.h"
};
@ -141,13 +153,12 @@ void heater_init() {
- PIOC_9 PWM3/4 02 SDA3
*/
if (NUM_HEATERS) { // At least one channel in use.
uint32_t freq;
uint8_t macro_mask;
// Auto-generate pin setup.
#undef DEFINE_HEATER
#define DEFINE_HEATER(name, pin, pwm) \
if (pwm && pin ## _TIMER) { \
uint32_t freq; \
uint8_t macro_mask; \
if (pin ## _TIMER == TIM1) { \
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; } /* turn on TIM1 */ \
else if (pin ## _TIMER == TIM2) { \
@ -174,7 +185,7 @@ void heater_init() {
pin ## _TIMER->ARR = PWM_SCALE - 1; /* reset on auto reload at 254 */ \
/* PWM_SCALE - 1, so CCR = 255 is full off. */ \
pin ## _TIMER-> EXPANDER(CCR, pin ## _CHANNEL,) = 0; /* start off */ \
freq = F_CPU / PWM_SCALE / pwm; /* Figure PWM freq. */ \
freq = F_CPU / PWM_SCALE / (pwm ? pwm : 1); /* Figure PWM freq. */ \
if (freq > 65535) \
freq = 65535; \
if (freq < 1) \
@ -198,13 +209,16 @@ void heater_init() {
/* invert the signal for negated timers*/ \
/* TODO: use this also with a XOR for inverted heaters later */ \
pin ## _TIMER->EGR |= TIM_EGR_UG; /* update generation */ \
pin ## _TIMER->CR1 |= TIM_CR1_CEN; /* enable counters */
pin ## _TIMER->CR1 |= TIM_CR1_CEN; /* enable counters */ \
} \
else { \
SET_OUTPUT(pin); \
WRITE(pin, 0); \
}
#include "config_wrapper.h"
#undef DEFINE_HEATER
} /* NUM_HEATERS */
#if 0
pid_init(i);
#endif /* 0 */
@ -226,12 +240,17 @@ void heater_set(heater_t index, uint8_t value) {
heaters_runtime[index].heater_output = value;
if (heaters[index].uses_pwm) {
// Remember, we scale, and duty cycle is inverted.
*heaters[index].ccr = (uint32_t)value * (PWM_SCALE / 255);
if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR("PWM %su = %lu\n"), index, *heaters[index].ccr);
}
else {
*(heaters[index].bsrr) =
heaters[index].masked_pin << ((value >= HEATER_THRESHOLD) ? 0 : 16);
}
if (value)
power_on();
}