Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
hardware_timer3.c
- Committer:
- rajathr
- Date:
- 2021-10-23
- Revision:
- 0:34ee385f4d2d
File content as of revision 0:34ee385f4d2d:
#include "hardware_timer3.h"
#include "gpio.h"
#include "stm32f4xx_rcc_mort.h"
#include "interrupt.h"
/*Below are defined all Timers and flags required */ //Mort: These should be in a timer.c or something like that file
#define TIM3_BASE_ADDRESS ((uint32_t)0x40000400)
#define TIM3_STATUS_REGISTER (TIM3_BASE_ADDRESS + 0x10)
#define TIM3_PSC_REGISTER (TIM3_BASE_ADDRESS + 0x28)
#define TIM3_AUTORELOAD_REGISTER (TIM3_BASE_ADDRESS + 0x2C)
#define TIM3_COUNTER_REGISTER (TIM3_BASE_ADDRESS + 0x24)
#define TIM3_CAPTURE_COMPARE_MODE_2_REGISTER (TIM3_BASE_ADDRESS + 0x1C)
#define TIM_CCMR13_OC1M_0 (0b00010000)
#define TIM_CCMR13_OC1M_1 (0b00100000)
#define TIM_CCMR13_OC1M_2 (0b01000000)
#define TIM_CCMR13_OCPE (0b00001000)
#define TIM_CCMR23_
#define TIM_CCMR13_OUTPUT 0x00
#define TIM3_COMPARE3_REGISTER (TIM3_BASE_ADDRESS + 0x3C)
#define TIM3_CAPTURE_COMPARE_ENABLE_REGISTER (TIM3_BASE_ADDRESS + 0x20)
#define TIM3_CR1_REGISTER1 (TIM3_BASE_ADDRESS + 0x00)
#define TIM3_CAPTURE_COMPARE_MODE_1_REGISTER (TIM3_BASE_ADDRESS + 0x18)
#define TIM3_CAPTURE_COMPARE_REGISTER_1 (TIM3_BASE_ADDRESS + 0x34)
#define TIM3_CCMR2_CC3S_OUTPUT (0b11111100)
#define TIM3_CCMR2_OC3FE (0b11111011)
#define TIM3_CCMR2_OC3PE (0b00001000)
#define TIM3_CCMR2_OC3M1 (0b11101111)
#define TIM3_CCMR2_OC3M2 (0b01100000)
#define TIM3_INTERRUPT_ENABLE_REGISTER (TIM3_BASE_ADDRESS + 0x0C)
void TMR3CH3OutputCompare(void)
{
uint16_t * reg;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enable Clock - SEE THE BUS UNDER WHICH THE REGISTER OR PERIPHERAL IS PRESENT
reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER
*reg = (~((uint16_t)0x01)); //Clear update event flag in STATUS REGISTER
reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER
*reg = 8999; //Setting the PRESCALER VALUE TO 899999, CALCULATE BY 90MHz/(Prescale + 1) --> ARR * 1/freq = 1Hz ---> freqcounter = 90MHz/(prescale +1)
reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER
*reg = 10000; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF
/*Setup mode resgister 2 to output compare and enable output*/ //(0b00000000 00110000)
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER; //READ CAPTURE COMPARE MODE REGISTER
*reg = *reg | TIM_CCMR13_OC1M_1 | TIM_CCMR13_OC1M_0 | TIM_CCMR13_OUTPUT;//Setting the Output Compare to the OC3M bit fields and enabling it as an output
reg = (uint16_t *)TIM3_COMPARE3_REGISTER; //READ VALUE OF COMPARE REGISTER
*reg = 2000; //Any value to count between two cycles- this is the value that we want to compare
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER
*reg = *reg | 0x0100; // Enabling TIM3 Channel3 - Setting the CC3E (Enable) bit in the CCER REGISTER
//Also keeping the default configuration for channel polarity
reg = (uint16_t *)TIM3_CR1_REGISTER1;
*reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1
}
void TMR3CH1GPIOCPin6asInputCapture(void)
{
uint16_t *reg;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Enable Clock
/*Clear Status register*/
reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER
*reg = (~((uint16_t)0x1)); //Clear update event flag in STATUS REGISTER
reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER
*reg = 9999; //Setting the PRESCALER VALUE TO 9999, CALCULATE BY 90MHz/(Prescale + 1)
reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER
*reg = 0xFFFF; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_1_REGISTER; //READ CAPTURE COMPARE MODE REGISTER
*reg = *reg | 0x01;//Configuring CC1 Channel as Input
//IC1 is mapped on TI1 - Configuring the REGISTER TO INPUT CAPTURE - CC1S BIT - 01
//ALL OTHER BITS TO BE SET FOR INPUT CAPTURE ARE 00's
//IC1PSC - 00 - NO PRESCALER
//IC1F - 0000 - No filter, sampling is done at fDTS - Input Capture 1 Filter
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER
*reg = *reg | 0x01; // Enabling TIM3 Channel1 - Setting the CC3E bit in the CCER REGISTER
//BY DEFAULT TIMER IS SENSITIVE TO RISING EDGE - ENABLE AND KEEP IT AS IT IS
reg = (uint16_t *)TIM3_CR1_REGISTER1;
*reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1
}
/* Question - Why dont we initialize or set bits of IC1PSC, IC1F AND IC1
WHY CAN'T IT BE *reg=0b00000001*/
uint16_t readCounterValueIfFlagIsSet(void)
{
uint16_t * reg1;
uint16_t * reg2;
uint16_t value;
value=0;
reg1 = (uint16_t *)TIM3_STATUS_REGISTER;
if( *reg1 & (uint16_t)0b10 == 0b10 )
{
reg2 = (uint16_t *)TIM3_CAPTURE_COMPARE_REGISTER_1;
value = *reg2;
//Do we need to clear the flag? - The TIM3_STATUS_REGISTER
}
return value;
}
//read status reguster,
//check if CCIF1 flag is set, if it is, you clear it rc_w0
//Statusregister = ~(CCIF1)
//and also you read the INput caputre register and return the value.
uint16_t readCounterRegister(void)
{
uint16_t *reg;
reg = (uint16_t *)TIM3_COUNTER_REGISTER;
return *reg;
}
void TMR3CH3OutputPWMMode1(void)
{
uint16_t *reg;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enable Clock - SEE THE BUS UNDER WHICH THE REGISTER OR PERIPHERAL IS PRESENT
reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER
*reg = (~((uint16_t)0x01)); //Clear update event flag in STATUS REGISTER
reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER
*reg = 35999; //Setting the PRESCALER VALUE TO 35999
reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER
*reg = 10000; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF
/*Setup mode resgister 2 to output compare and enable output*/ //(0b00000000 01101000)
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER; //READ CAPTURE COMPARE MODE REGISTER
*reg = *reg | TIM3_CCMR2_OC3M2 & TIM3_CCMR2_OC3M1 | TIM3_CCMR2_OC3PE & TIM3_CCMR2_OC3FE & TIM3_CCMR2_CC3S_OUTPUT ;//Setting the PWM Mode 1 to the OC3M bit fields and enabling it as an output
reg = (uint16_t *)TIM3_COMPARE3_REGISTER; //READ VALUE OF COMPARE REGISTER
*reg = 5000; //We want half of 0.5Hz - Autoreload Register is 0.5Hz and Compare Value is at 0.25Hz
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER
*reg = *reg | 0x0100; // Enabling TIM3 Channel3 - Setting the CC3E (Enable) bit in the CCER REGISTER
//Also keeping the default configuration for channel polarity
reg = (uint16_t *)TIM3_CR1_REGISTER1;
*reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1
}
void initTimer3ToInterrupt(void)
{
uint16_t * reg;
uint16_t prescalervalue2, autoreloadvalue;
/* Timer 3 APB clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/*enable the interrupt that would go to timer 3*/
enableNVIC_Timer3();
/* Compute Prescale and Autorreload */
prescalervalue2 = 35999; //Frequency of clock is 90 MHz
autoreloadvalue = 10000;
/* Clear any pending flags in the status register */
reg = (uint16_t *)TIM3_STATUS_REGISTER;
*reg = 0;
/* Set Prescale and Autorreload */
reg = (uint16_t *)TIM3_PSC_REGISTER;
*reg = prescalervalue2;
reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER;
*reg = autoreloadvalue;
/* Set Compare Value */
reg = (uint16_t *)TIM3_COMPARE3_REGISTER;
*reg = autoreloadvalue/2;
/* Enable Preload Register (Don’t HAVE to, but good practice) */
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER;
*reg = *reg | 0b00001000;
/*enable the TIM3 channel 3 counter and keep the default configuration for channel polarity*/
reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER;
*reg = *reg | 0x0100;
/*enable interrupt on capture compare channel 3*/
reg = (uint16_t *)TIM3_INTERRUPT_ENABLE_REGISTER;
*reg = (0x8 | 0x1);
/*enable timer 3*/
reg = (uint16_t *)TIM3_CR1_REGISTER1;
*reg = *reg | (uint16_t)0x01;
}