Here I wrote a small fragment to reproduce the issue
Both timers 1 and 3 are working
With timer3 I feed the T1 input capture (PA8) to read the pwm frequency, the thing is that I need to produce the pwm doing a DigitalWrite inside pwm isr (and use another pin such as PB6 in this case) rather than being able to use the hardware PB0 T3 channel 3 pin
PB6 ----> PA8 reads the freq (pb6 is toggling inside pwm ISR by a digitalWrite)
PB0 ----> PA8 nothing read
I tried defining T3channel3 as PB0_ALT1 and PB0 with no luck
Hopefully there's some aditional insight I'm not seeing, thanks in advance
Note that I'm using a tft display to debug, cause I dont have a scope and never being able to use serial port with stlink either...
regards
julian
Code: Select all
#include <Arduino.h>
const int PIN_LED = PB6;
///TIMER 3
#define pin_T3_CH_3_PWM PB0_ALT1 //PB0
uint32_t T3_channel_3;
HardwareTimer *gTimer3PWM = new HardwareTimer(TIM3);
///TIMER 1
const uint32_t CPU_CLOCK = 72000000; // STM32 clock (72 MHz)
const uint32_t TIMER1_PRESCALER = 72; // Prescaler value (72 gives 1 MHz timer frequency, 1 µs per tick)
#define pin_T1_CH1 PA8 //
HardwareTimer *gTimer1 = new HardwareTimer(TIM1);
//esta macro fue sacada de st7789_Fast.h
#define INCLUDE_BRG_to565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
#define TFT_DEF_black 0x0000
//BLUE GREEN RED
#define TFT_DEF_lila 0xf81F //0 OK
#define TFT_DEF_rojo 0x001F //1 ok
#define TFT_DEF_naranja INCLUDE_BRG_to565(25,102,225) // 2 OK
#define TFT_DEF_amarillo INCLUDE_BRG_to565(0,255,255) //3
#define TFT_DEF_verde_claro INCLUDE_BRG_to565(0,255,0) //4
#define TFT_DEF_verde_oscuro INCLUDE_BRG_to565(60,255,60)//5
#define TFT_DEF_azul INCLUDE_BRG_to565(255,0,0) //6
#define TFT_DEF_celeste 0xFFE0 // 7 OK
#define TFT_DEF_gris_claro INCLUDE_BRG_to565(200,200,200) // 8 OK
#define TFT_DEF_gris_oscuro INCLUDE_BRG_to565(150,150,150) // 9 OK
#define TFT_DEF_white 0xFFFF //10 OK
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
//#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
//ANDANDO con el display 188
#define TFT_CS PB7
#define TFT_DC PB8
#define TFT_RST PB9
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Variables for pulse measurement
volatile uint32_t v_lastCapture = 0; // Last captured timer value
volatile uint32_t v_periodTicks = 0; // Calculated period in timer ticks
volatile uint32_t v_overflowCount = 0; // Overflow counter
volatile bool v_newPeriodAvailable = false; // Flag indicating a new period is available
volatile uint32_t v_pulseCount = 0; // Total pulse count
void setup() {
SPI.begin();
tft.initR( INITR_GREENTAB );
tft.fillScreen(TFT_DEF_black);
tft.setRotation(2);
digitalWrite(PIN_LED, LOW);
pinMode(PIN_LED, OUTPUT);
Serial.begin(115200); // Start serial communication
T3_channel_3 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin_T3_CH_3_PWM), PinMap_PWM));
gTimer3PWM->setMode(T3_channel_3, TIMER_OUTPUT_COMPARE_PWM1, pin_T3_CH_3_PWM);
gTimer3PWM->setOverflow(125, HERTZ_FORMAT); //
gTimer3PWM->setCaptureCompare(T3_channel_3, 50, PERCENT_COMPARE_FORMAT); // 50% duty cycle
gTimer3PWM->attachInterrupt(IRQ_T3_Update_IT_callback); ///OVERFLOW IRQ
gTimer3PWM->attachInterrupt(T3_channel_3, IRQ_T3_Compare_IT_callback);
gTimer3PWM->resume();
// Timer 1 configuration for input capture
pinMode(pin_T1_CH1, INPUT);
gTimer1->setPrescaleFactor(TIMER1_PRESCALER); // Set prescaler to 72
gTimer1->setOverflow(0xFFFFFFFF, TICK_FORMAT); // Use full 32-bit counter
gTimer1->setMode(1, TIMER_INPUT_CAPTURE_RISING, pin_T1_CH1); // Capture rising edges
// Attach callbacks for input capture and overflow
gTimer1->attachInterrupt(1, timerCaptureCallback); // Capture interrupt
gTimer1->attachInterrupt(timerOverflowCallback); // Overflow interrupt
gTimer1->resume(); // Start the timer
}
void loop() {
static int i=0;
if (v_newPeriodAvailable) {
disableTimer1Interrupts();
uint32_t periodTicks = v_periodTicks;
v_newPeriodAvailable = false;
enableTimer1Interrupts();
float frequencyHz = 0.0;
if (periodTicks > 0) {
// (se podrìa hacer todo en segundos y usar 1.0) Convert period ticks to time in microseconds
float periodMicroseconds = periodTicks * (1.0 / CPU_CLOCK * TIMER1_PRESCALER) * 1e6;
// Calculate frequency in Hz
frequencyHz = 1000000.0 / periodMicroseconds;
}
static int iHz = 0;
iHz += 50;
if (iHz>1000){
iHz=50;
}
gTimer3PWM->setOverflow(iHz, HERTZ_FORMAT); //
//tft.fillScreen(TFT_DEF_black);
tft.setTextColor(TFT_DEF_naranja,TFT_DEF_black );
tft.setCursor(0 , 0);
tft.setTextSize(2);
tft.print(frequencyHz);
delay(500);
}
}
void timerCaptureCallback() {
uint32_t currentCapture = TIM1->CCR1; // Capture value from Timer 1, Channel 1
// Calculate the period in ticks
if (v_lastCapture <= currentCapture) {
v_periodTicks = currentCapture - v_lastCapture + (v_overflowCount << 32);
} else {
v_periodTicks = (0xFFFFFFFF - v_lastCapture + currentCapture) + (v_overflowCount - 1) << 32;
}
v_lastCapture = currentCapture; // Update the last capture value
v_overflowCount = 0; // Reset overflow counter
v_newPeriodAvailable = true; // Set flag for new period
}
void timerOverflowCallback() {
v_overflowCount++; // Increment the overflow counter
}
void IRQ_T3_Update_IT_callback(void){ // Update event correspond to Rising edge of PWM when configured in PWM1 mode
digitalWrite(PIN_LED, HIGH);
}
void IRQ_T3_Compare_IT_callback(void){ // Compare match event correspond to falling edge of PWM when configured in PWM1 mode
digitalWrite(PIN_LED, LOW);
}
// Disable only TIM1 interrupts
void disableTimer1Interrupts() {
NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn); // Disable TIM1 overflow interrupt
NVIC_DisableIRQ(TIM1_CC_IRQn); // Disable TIM1 capture/compare interrupt
}
// Enable only TIM1 interrupts
void enableTimer1Interrupts() {
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); // Enable TIM1 overflow interrupt
NVIC_EnableIRQ(TIM1_CC_IRQn); // Enable TIM1 capture/compare interrupt
}