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@0:34ee385f4d2d, 2021-10-23 (annotated)
- Committer:
- rajathr
- Date:
- Sat Oct 23 05:49:09 2021 +0000
- Revision:
- 0:34ee385f4d2d
At 23rd Oct 21 - All Code
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| rajathr | 0:34ee385f4d2d | 1 | #include "hardware_timer3.h" |
| rajathr | 0:34ee385f4d2d | 2 | #include "gpio.h" |
| rajathr | 0:34ee385f4d2d | 3 | #include "stm32f4xx_rcc_mort.h" |
| rajathr | 0:34ee385f4d2d | 4 | #include "interrupt.h" |
| rajathr | 0:34ee385f4d2d | 5 | |
| rajathr | 0:34ee385f4d2d | 6 | |
| rajathr | 0:34ee385f4d2d | 7 | /*Below are defined all Timers and flags required */ //Mort: These should be in a timer.c or something like that file |
| rajathr | 0:34ee385f4d2d | 8 | #define TIM3_BASE_ADDRESS ((uint32_t)0x40000400) |
| rajathr | 0:34ee385f4d2d | 9 | #define TIM3_STATUS_REGISTER (TIM3_BASE_ADDRESS + 0x10) |
| rajathr | 0:34ee385f4d2d | 10 | #define TIM3_PSC_REGISTER (TIM3_BASE_ADDRESS + 0x28) |
| rajathr | 0:34ee385f4d2d | 11 | #define TIM3_AUTORELOAD_REGISTER (TIM3_BASE_ADDRESS + 0x2C) |
| rajathr | 0:34ee385f4d2d | 12 | #define TIM3_COUNTER_REGISTER (TIM3_BASE_ADDRESS + 0x24) |
| rajathr | 0:34ee385f4d2d | 13 | #define TIM3_CAPTURE_COMPARE_MODE_2_REGISTER (TIM3_BASE_ADDRESS + 0x1C) |
| rajathr | 0:34ee385f4d2d | 14 | #define TIM_CCMR13_OC1M_0 (0b00010000) |
| rajathr | 0:34ee385f4d2d | 15 | #define TIM_CCMR13_OC1M_1 (0b00100000) |
| rajathr | 0:34ee385f4d2d | 16 | #define TIM_CCMR13_OC1M_2 (0b01000000) |
| rajathr | 0:34ee385f4d2d | 17 | #define TIM_CCMR13_OCPE (0b00001000) |
| rajathr | 0:34ee385f4d2d | 18 | #define TIM_CCMR23_ |
| rajathr | 0:34ee385f4d2d | 19 | #define TIM_CCMR13_OUTPUT 0x00 |
| rajathr | 0:34ee385f4d2d | 20 | #define TIM3_COMPARE3_REGISTER (TIM3_BASE_ADDRESS + 0x3C) |
| rajathr | 0:34ee385f4d2d | 21 | #define TIM3_CAPTURE_COMPARE_ENABLE_REGISTER (TIM3_BASE_ADDRESS + 0x20) |
| rajathr | 0:34ee385f4d2d | 22 | #define TIM3_CR1_REGISTER1 (TIM3_BASE_ADDRESS + 0x00) |
| rajathr | 0:34ee385f4d2d | 23 | #define TIM3_CAPTURE_COMPARE_MODE_1_REGISTER (TIM3_BASE_ADDRESS + 0x18) |
| rajathr | 0:34ee385f4d2d | 24 | #define TIM3_CAPTURE_COMPARE_REGISTER_1 (TIM3_BASE_ADDRESS + 0x34) |
| rajathr | 0:34ee385f4d2d | 25 | |
| rajathr | 0:34ee385f4d2d | 26 | #define TIM3_CCMR2_CC3S_OUTPUT (0b11111100) |
| rajathr | 0:34ee385f4d2d | 27 | #define TIM3_CCMR2_OC3FE (0b11111011) |
| rajathr | 0:34ee385f4d2d | 28 | #define TIM3_CCMR2_OC3PE (0b00001000) |
| rajathr | 0:34ee385f4d2d | 29 | #define TIM3_CCMR2_OC3M1 (0b11101111) |
| rajathr | 0:34ee385f4d2d | 30 | #define TIM3_CCMR2_OC3M2 (0b01100000) |
| rajathr | 0:34ee385f4d2d | 31 | |
| rajathr | 0:34ee385f4d2d | 32 | #define TIM3_INTERRUPT_ENABLE_REGISTER (TIM3_BASE_ADDRESS + 0x0C) |
| rajathr | 0:34ee385f4d2d | 33 | |
| rajathr | 0:34ee385f4d2d | 34 | |
| rajathr | 0:34ee385f4d2d | 35 | void TMR3CH3OutputCompare(void) |
| rajathr | 0:34ee385f4d2d | 36 | { |
| rajathr | 0:34ee385f4d2d | 37 | uint16_t * reg; |
| rajathr | 0:34ee385f4d2d | 38 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enable Clock - SEE THE BUS UNDER WHICH THE REGISTER OR PERIPHERAL IS PRESENT |
| rajathr | 0:34ee385f4d2d | 39 | |
| rajathr | 0:34ee385f4d2d | 40 | reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 41 | *reg = (~((uint16_t)0x01)); //Clear update event flag in STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 42 | |
| rajathr | 0:34ee385f4d2d | 43 | reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER |
| rajathr | 0:34ee385f4d2d | 44 | *reg = 8999; //Setting the PRESCALER VALUE TO 899999, CALCULATE BY 90MHz/(Prescale + 1) --> ARR * 1/freq = 1Hz ---> freqcounter = 90MHz/(prescale +1) |
| rajathr | 0:34ee385f4d2d | 45 | |
| rajathr | 0:34ee385f4d2d | 46 | reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER |
| rajathr | 0:34ee385f4d2d | 47 | *reg = 10000; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF |
| rajathr | 0:34ee385f4d2d | 48 | |
| rajathr | 0:34ee385f4d2d | 49 | /*Setup mode resgister 2 to output compare and enable output*/ //(0b00000000 00110000) |
| rajathr | 0:34ee385f4d2d | 50 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER; //READ CAPTURE COMPARE MODE REGISTER |
| rajathr | 0:34ee385f4d2d | 51 | *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 |
| rajathr | 0:34ee385f4d2d | 52 | |
| rajathr | 0:34ee385f4d2d | 53 | reg = (uint16_t *)TIM3_COMPARE3_REGISTER; //READ VALUE OF COMPARE REGISTER |
| rajathr | 0:34ee385f4d2d | 54 | *reg = 2000; //Any value to count between two cycles- this is the value that we want to compare |
| rajathr | 0:34ee385f4d2d | 55 | |
| rajathr | 0:34ee385f4d2d | 56 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER |
| rajathr | 0:34ee385f4d2d | 57 | *reg = *reg | 0x0100; // Enabling TIM3 Channel3 - Setting the CC3E (Enable) bit in the CCER REGISTER |
| rajathr | 0:34ee385f4d2d | 58 | |
| rajathr | 0:34ee385f4d2d | 59 | //Also keeping the default configuration for channel polarity |
| rajathr | 0:34ee385f4d2d | 60 | reg = (uint16_t *)TIM3_CR1_REGISTER1; |
| rajathr | 0:34ee385f4d2d | 61 | *reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1 |
| rajathr | 0:34ee385f4d2d | 62 | } |
| rajathr | 0:34ee385f4d2d | 63 | |
| rajathr | 0:34ee385f4d2d | 64 | |
| rajathr | 0:34ee385f4d2d | 65 | void TMR3CH1GPIOCPin6asInputCapture(void) |
| rajathr | 0:34ee385f4d2d | 66 | { |
| rajathr | 0:34ee385f4d2d | 67 | uint16_t *reg; |
| rajathr | 0:34ee385f4d2d | 68 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Enable Clock |
| rajathr | 0:34ee385f4d2d | 69 | |
| rajathr | 0:34ee385f4d2d | 70 | /*Clear Status register*/ |
| rajathr | 0:34ee385f4d2d | 71 | reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 72 | *reg = (~((uint16_t)0x1)); //Clear update event flag in STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 73 | |
| rajathr | 0:34ee385f4d2d | 74 | reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER |
| rajathr | 0:34ee385f4d2d | 75 | *reg = 9999; //Setting the PRESCALER VALUE TO 9999, CALCULATE BY 90MHz/(Prescale + 1) |
| rajathr | 0:34ee385f4d2d | 76 | |
| rajathr | 0:34ee385f4d2d | 77 | reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER |
| rajathr | 0:34ee385f4d2d | 78 | *reg = 0xFFFF; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF |
| rajathr | 0:34ee385f4d2d | 79 | |
| rajathr | 0:34ee385f4d2d | 80 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_1_REGISTER; //READ CAPTURE COMPARE MODE REGISTER |
| rajathr | 0:34ee385f4d2d | 81 | *reg = *reg | 0x01;//Configuring CC1 Channel as Input |
| rajathr | 0:34ee385f4d2d | 82 | //IC1 is mapped on TI1 - Configuring the REGISTER TO INPUT CAPTURE - CC1S BIT - 01 |
| rajathr | 0:34ee385f4d2d | 83 | //ALL OTHER BITS TO BE SET FOR INPUT CAPTURE ARE 00's |
| rajathr | 0:34ee385f4d2d | 84 | //IC1PSC - 00 - NO PRESCALER |
| rajathr | 0:34ee385f4d2d | 85 | //IC1F - 0000 - No filter, sampling is done at fDTS - Input Capture 1 Filter |
| rajathr | 0:34ee385f4d2d | 86 | |
| rajathr | 0:34ee385f4d2d | 87 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER |
| rajathr | 0:34ee385f4d2d | 88 | *reg = *reg | 0x01; // Enabling TIM3 Channel1 - Setting the CC3E bit in the CCER REGISTER |
| rajathr | 0:34ee385f4d2d | 89 | //BY DEFAULT TIMER IS SENSITIVE TO RISING EDGE - ENABLE AND KEEP IT AS IT IS |
| rajathr | 0:34ee385f4d2d | 90 | |
| rajathr | 0:34ee385f4d2d | 91 | reg = (uint16_t *)TIM3_CR1_REGISTER1; |
| rajathr | 0:34ee385f4d2d | 92 | *reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1 |
| rajathr | 0:34ee385f4d2d | 93 | } |
| rajathr | 0:34ee385f4d2d | 94 | |
| rajathr | 0:34ee385f4d2d | 95 | /* Question - Why dont we initialize or set bits of IC1PSC, IC1F AND IC1 |
| rajathr | 0:34ee385f4d2d | 96 | WHY CAN'T IT BE *reg=0b00000001*/ |
| rajathr | 0:34ee385f4d2d | 97 | |
| rajathr | 0:34ee385f4d2d | 98 | uint16_t readCounterValueIfFlagIsSet(void) |
| rajathr | 0:34ee385f4d2d | 99 | { |
| rajathr | 0:34ee385f4d2d | 100 | uint16_t * reg1; |
| rajathr | 0:34ee385f4d2d | 101 | uint16_t * reg2; |
| rajathr | 0:34ee385f4d2d | 102 | uint16_t value; |
| rajathr | 0:34ee385f4d2d | 103 | value=0; |
| rajathr | 0:34ee385f4d2d | 104 | |
| rajathr | 0:34ee385f4d2d | 105 | reg1 = (uint16_t *)TIM3_STATUS_REGISTER; |
| rajathr | 0:34ee385f4d2d | 106 | |
| rajathr | 0:34ee385f4d2d | 107 | if( *reg1 & (uint16_t)0b10 == 0b10 ) |
| rajathr | 0:34ee385f4d2d | 108 | { |
| rajathr | 0:34ee385f4d2d | 109 | reg2 = (uint16_t *)TIM3_CAPTURE_COMPARE_REGISTER_1; |
| rajathr | 0:34ee385f4d2d | 110 | value = *reg2; |
| rajathr | 0:34ee385f4d2d | 111 | //Do we need to clear the flag? - The TIM3_STATUS_REGISTER |
| rajathr | 0:34ee385f4d2d | 112 | } |
| rajathr | 0:34ee385f4d2d | 113 | |
| rajathr | 0:34ee385f4d2d | 114 | return value; |
| rajathr | 0:34ee385f4d2d | 115 | |
| rajathr | 0:34ee385f4d2d | 116 | } |
| rajathr | 0:34ee385f4d2d | 117 | |
| rajathr | 0:34ee385f4d2d | 118 | //read status reguster, |
| rajathr | 0:34ee385f4d2d | 119 | //check if CCIF1 flag is set, if it is, you clear it rc_w0 |
| rajathr | 0:34ee385f4d2d | 120 | //Statusregister = ~(CCIF1) |
| rajathr | 0:34ee385f4d2d | 121 | //and also you read the INput caputre register and return the value. |
| rajathr | 0:34ee385f4d2d | 122 | |
| rajathr | 0:34ee385f4d2d | 123 | |
| rajathr | 0:34ee385f4d2d | 124 | |
| rajathr | 0:34ee385f4d2d | 125 | |
| rajathr | 0:34ee385f4d2d | 126 | uint16_t readCounterRegister(void) |
| rajathr | 0:34ee385f4d2d | 127 | { |
| rajathr | 0:34ee385f4d2d | 128 | uint16_t *reg; |
| rajathr | 0:34ee385f4d2d | 129 | reg = (uint16_t *)TIM3_COUNTER_REGISTER; |
| rajathr | 0:34ee385f4d2d | 130 | return *reg; |
| rajathr | 0:34ee385f4d2d | 131 | } |
| rajathr | 0:34ee385f4d2d | 132 | |
| rajathr | 0:34ee385f4d2d | 133 | void TMR3CH3OutputPWMMode1(void) |
| rajathr | 0:34ee385f4d2d | 134 | { |
| rajathr | 0:34ee385f4d2d | 135 | uint16_t *reg; |
| rajathr | 0:34ee385f4d2d | 136 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//Enable Clock - SEE THE BUS UNDER WHICH THE REGISTER OR PERIPHERAL IS PRESENT |
| rajathr | 0:34ee385f4d2d | 137 | |
| rajathr | 0:34ee385f4d2d | 138 | reg = (uint16_t *)TIM3_STATUS_REGISTER; //Read flag value of STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 139 | *reg = (~((uint16_t)0x01)); //Clear update event flag in STATUS REGISTER |
| rajathr | 0:34ee385f4d2d | 140 | |
| rajathr | 0:34ee385f4d2d | 141 | reg = (uint16_t *)TIM3_PSC_REGISTER; //Read value of PRESCALER REGISTER |
| rajathr | 0:34ee385f4d2d | 142 | *reg = 35999; //Setting the PRESCALER VALUE TO 35999 |
| rajathr | 0:34ee385f4d2d | 143 | |
| rajathr | 0:34ee385f4d2d | 144 | reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; //Read value of AUTORELOAD REGISTER |
| rajathr | 0:34ee385f4d2d | 145 | *reg = 10000; //Count till 65535 or 2^16-1, DEFINES LIMIT UPTO WHICH COUNTER SHOULD COUNT,POST THIS IT WILL RESET ITSELF |
| rajathr | 0:34ee385f4d2d | 146 | |
| rajathr | 0:34ee385f4d2d | 147 | /*Setup mode resgister 2 to output compare and enable output*/ //(0b00000000 01101000) |
| rajathr | 0:34ee385f4d2d | 148 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER; //READ CAPTURE COMPARE MODE REGISTER |
| rajathr | 0:34ee385f4d2d | 149 | *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 |
| rajathr | 0:34ee385f4d2d | 150 | |
| rajathr | 0:34ee385f4d2d | 151 | reg = (uint16_t *)TIM3_COMPARE3_REGISTER; //READ VALUE OF COMPARE REGISTER |
| rajathr | 0:34ee385f4d2d | 152 | *reg = 5000; //We want half of 0.5Hz - Autoreload Register is 0.5Hz and Compare Value is at 0.25Hz |
| rajathr | 0:34ee385f4d2d | 153 | |
| rajathr | 0:34ee385f4d2d | 154 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; //READ VALUE OF CAPTURE COMPARE ENABLE REGISTER |
| rajathr | 0:34ee385f4d2d | 155 | *reg = *reg | 0x0100; // Enabling TIM3 Channel3 - Setting the CC3E (Enable) bit in the CCER REGISTER |
| rajathr | 0:34ee385f4d2d | 156 | |
| rajathr | 0:34ee385f4d2d | 157 | //Also keeping the default configuration for channel polarity |
| rajathr | 0:34ee385f4d2d | 158 | reg = (uint16_t *)TIM3_CR1_REGISTER1; |
| rajathr | 0:34ee385f4d2d | 159 | *reg = *reg | ((uint16_t)0x01);//Enabling the Timer3 subsystem by setting the CEN bit in TIM3_CR1 |
| rajathr | 0:34ee385f4d2d | 160 | } |
| rajathr | 0:34ee385f4d2d | 161 | |
| rajathr | 0:34ee385f4d2d | 162 | void initTimer3ToInterrupt(void) |
| rajathr | 0:34ee385f4d2d | 163 | { |
| rajathr | 0:34ee385f4d2d | 164 | uint16_t * reg; |
| rajathr | 0:34ee385f4d2d | 165 | uint16_t prescalervalue2, autoreloadvalue; |
| rajathr | 0:34ee385f4d2d | 166 | /* Timer 3 APB clock enable */ |
| rajathr | 0:34ee385f4d2d | 167 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); |
| rajathr | 0:34ee385f4d2d | 168 | /*enable the interrupt that would go to timer 3*/ |
| rajathr | 0:34ee385f4d2d | 169 | enableNVIC_Timer3(); |
| rajathr | 0:34ee385f4d2d | 170 | /* Compute Prescale and Autorreload */ |
| rajathr | 0:34ee385f4d2d | 171 | prescalervalue2 = 35999; //Frequency of clock is 90 MHz |
| rajathr | 0:34ee385f4d2d | 172 | autoreloadvalue = 10000; |
| rajathr | 0:34ee385f4d2d | 173 | /* Clear any pending flags in the status register */ |
| rajathr | 0:34ee385f4d2d | 174 | reg = (uint16_t *)TIM3_STATUS_REGISTER; |
| rajathr | 0:34ee385f4d2d | 175 | *reg = 0; |
| rajathr | 0:34ee385f4d2d | 176 | /* Set Prescale and Autorreload */ |
| rajathr | 0:34ee385f4d2d | 177 | reg = (uint16_t *)TIM3_PSC_REGISTER; |
| rajathr | 0:34ee385f4d2d | 178 | *reg = prescalervalue2; |
| rajathr | 0:34ee385f4d2d | 179 | reg = (uint16_t *)TIM3_AUTORELOAD_REGISTER; |
| rajathr | 0:34ee385f4d2d | 180 | *reg = autoreloadvalue; |
| rajathr | 0:34ee385f4d2d | 181 | /* Set Compare Value */ |
| rajathr | 0:34ee385f4d2d | 182 | reg = (uint16_t *)TIM3_COMPARE3_REGISTER; |
| rajathr | 0:34ee385f4d2d | 183 | *reg = autoreloadvalue/2; |
| rajathr | 0:34ee385f4d2d | 184 | /* Enable Preload Register (Don’t HAVE to, but good practice) */ |
| rajathr | 0:34ee385f4d2d | 185 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_MODE_2_REGISTER; |
| rajathr | 0:34ee385f4d2d | 186 | *reg = *reg | 0b00001000; |
| rajathr | 0:34ee385f4d2d | 187 | /*enable the TIM3 channel 3 counter and keep the default configuration for channel polarity*/ |
| rajathr | 0:34ee385f4d2d | 188 | reg = (uint16_t *)TIM3_CAPTURE_COMPARE_ENABLE_REGISTER; |
| rajathr | 0:34ee385f4d2d | 189 | *reg = *reg | 0x0100; |
| rajathr | 0:34ee385f4d2d | 190 | /*enable interrupt on capture compare channel 3*/ |
| rajathr | 0:34ee385f4d2d | 191 | reg = (uint16_t *)TIM3_INTERRUPT_ENABLE_REGISTER; |
| rajathr | 0:34ee385f4d2d | 192 | *reg = (0x8 | 0x1); |
| rajathr | 0:34ee385f4d2d | 193 | /*enable timer 3*/ |
| rajathr | 0:34ee385f4d2d | 194 | reg = (uint16_t *)TIM3_CR1_REGISTER1; |
| rajathr | 0:34ee385f4d2d | 195 | *reg = *reg | (uint16_t)0x01; |
| rajathr | 0:34ee385f4d2d | 196 | } |
| rajathr | 0:34ee385f4d2d | 197 | |
| rajathr | 0:34ee385f4d2d | 198 |