0

I have an arduino Giga (STM32H7), and I'm trying to generate PWM's. I succeeded using alternate function AF9 of PA7 (digital pin 5), which uses TIM14_CH1. Now, using the exact same code (as far as I can see) but using PA2/PA3 (digital pins 3 and 2) and alternate function AF4 (which use TIM15_CH1/2) I don't get any output for those pins. TIM15 does turn on though, i.e., it starts counting and restarts at the appropriate time.

int VolRepTime = 11000;     // Time to acquire one volume, in microseconds.
int Laser1UpTime = 8000;    // Time Laser1 trigger should stay up, in microseconds.
int Laser2UpTime = 5000;    // Time Laser2 trigger should stay up, in microseconds.
int Laser3UpTime = 4000;    // Time Laser3 trigger should stay up, in microseconds.

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  
  initTimers();
  initPins();

  Trigger1(Laser1UpTime, VolRepTime);
  Trigger2(Laser2UpTime, VolRepTime);  
  Trigger3(Laser3UpTime, VolRepTime);

}


void initTimers(){

  RCC->APB1LENR |= RCC_APB1LENR_TIM14EN;    // Enable use of TIM14
  RCC->APB2ENR  |= RCC_APB2ENR_TIM15EN;     // Enable use of TIM15

  // Set PWM mode.
  TIM14->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC1M_Pos );    //  PWM mode 1 - Channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  TIM15->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC1M_Pos );    //  PWM mode 1 - Channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  TIM15->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC2M_Pos );    //  PWM mode 1 - Channel 2 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  

  TIM14->CCER |= TIM_CCER_CC1E;  // Enables Capture/Compare for Channel 1.
  TIM15->CCER |= TIM_CCER_CC1E;  // Enables Capture/Compare for Channel 1.
  TIM15->CCER |= TIM_CCER_CC2E;  // Enables Capture/Compare for Channel 2.

  TIM14->DIER |= ( TIM_DIER_CC1IE | TIM_DIER_UIE );    // Update and Capture/Compare interrupts enabled
  TIM14->SR &= ~( TIM_SR_CC1IF | TIM_SR_UIF );         // Clear the interrupts

  TIM15->DIER |= ( TIM_DIER_CC1IE | TIM_DIER_UIE );    
  TIM15->SR &= ~( TIM_SR_CC1IF | TIM_SR_UIF );         
  TIM15->DIER |= ( TIM_DIER_CC2IE | TIM_DIER_UIE );  
  TIM15->SR &= ~( TIM_SR_CC2IF | TIM_SR_UIF );         

}



void initPins(){
  // Enables GPIOA. Gives access to digital pins 2, 3 and 5.
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;

  // Digital port = microcontroller port - [ModeRegisterBits]:
  // D2 = PA3 - [6 7]
  // D3 = PA2 - [4 5]
  // D5 = PA7 - [14 15]
  
  // For  Alternate function mode set bits to 10.
  // Set bits manually for now... (FIX ME)

  GPIOA->MODER = 0b10101011111111111011111110101111;
  


  // See page 89 of Datasheet.
  // Digital port = microcontroller port -> Alternate function - Corresponding timer
  // D2 = PA3-> AF4 - TIM15_CH2;
  // D3 = PA2-> AF4 - TIM15_CH1;
  // D5 = PA7-> AF9 - TIM14_CH1;

  // Set which alternate function each port should use.
  GPIOA->AFR[0] |= ( 0x4UL << 12);  // AF4 at AFR3
  GPIOA->AFR[0] |= ( 0x4UL << 8);   // AF4 at AFR2
  GPIOA->AFR[0] |= ( 0x9UL << 28);  // AF9 at AFR7

}


void Trigger1(int UpTime, int VolRepTime){
  TIM14->PSC = 240-1;             // Prescaler set so that 1 tick is 1 microsecond.
  TIM14->ARR = VolRepTime-1;      // Counter resets after reaching this value.
  TIM14->CCR1 = UpTime;           // Compare Register: Signal goes down after this time.        
}

void Trigger2(int UpTime, int VolRepTime){
  TIM15->PSC = 240-1;             
  TIM15->ARR = VolRepTime-1;      
  TIM15->CCR1 = UpTime;        
}

void Trigger3(int UpTime, int VolRepTime){
  TIM15->PSC = 240-1;             
  TIM15->ARR = VolRepTime-1;      
  TIM15->CCR2 = UpTime;        
}



void onoff(){
  // Turns TIM14/TIM15 on and off.
  TIM14->CR1 ^= TIM_CR1_CEN; 
  TIM15->CR1 ^= TIM_CR1_CEN;

}


void loop()
{
  delay(1000);
  
  if(Serial.read()!=-1){
    onoff();
  }
  Serial.println(TIM15->CNT);
}

Even setting TIMx_CCMR1_OCxM to 0x5UL ("Force active level - OC1REF is forced high.") doesn't work for TIM15. I've also tried using TIM16 (which uses GPIOB), which I couldn't get to work either, which is weird because the functionality is identical to that of TIM14. Any help is greatly appreciated!

1 Answer 1

0

TIM15/16/17 have complementary outputs (with Break), which means that you have to set TIMx_BDTR.MOE for the outputs to work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.