Skeleton program for Federico's 4YP project.

Dependencies:   WebSocketClient WiflyInterface mbed messages

Fork of IoT_Ex by Damien Frost

Committer:
defrost
Date:
Tue Nov 29 15:02:01 2016 +0000
Revision:
10:e8b66718a103
- Works

Who changed what in which revision?

UserRevisionLine numberNew contents of line
defrost 10:e8b66718a103 1 // **************
defrost 10:e8b66718a103 2 // * iQ_PWM.cpp *
defrost 10:e8b66718a103 3 // **************
defrost 10:e8b66718a103 4 //
defrost 10:e8b66718a103 5 // Created: 2015/03/19
defrost 10:e8b66718a103 6 // By: Damien Frost
defrost 10:e8b66718a103 7
defrost 10:e8b66718a103 8 #include "math.h"
defrost 10:e8b66718a103 9 #include "mbed.h"
defrost 10:e8b66718a103 10 #include "globals.h"
defrost 10:e8b66718a103 11 #include "pwm.h"
defrost 10:e8b66718a103 12 #include "ADC.h"
defrost 10:e8b66718a103 13 #include "Commands.h"
defrost 10:e8b66718a103 14
defrost 10:e8b66718a103 15 #define DEBUG
defrost 10:e8b66718a103 16 #define INFOMESSAGES
defrost 10:e8b66718a103 17 #define WARNMESSAGES
defrost 10:e8b66718a103 18 #define ERRMESSAGES
defrost 10:e8b66718a103 19 #define FUNCNAME "PWM"
defrost 10:e8b66718a103 20 #include "messages.h"
defrost 10:e8b66718a103 21
defrost 10:e8b66718a103 22
defrost 10:e8b66718a103 23 // Configures the PWM for use, using an initial duty cycle and period in us.
defrost 10:e8b66718a103 24 void ConfigurePWM(float duty_us, float period_us){
defrost 10:e8b66718a103 25 unsigned int value;
defrost 10:e8b66718a103 26 float newVal;
defrost 10:e8b66718a103 27
defrost 10:e8b66718a103 28 // Ensure power is turned on
defrost 10:e8b66718a103 29 // Grabbed from lines 54-57 of analogin_api.h, modified for PWM
defrost 10:e8b66718a103 30 // This turns on the clock to Ports A, B, and C
defrost 10:e8b66718a103 31 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
defrost 10:e8b66718a103 32 // This turns on the clock to the Time 1:
defrost 10:e8b66718a103 33 RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
defrost 10:e8b66718a103 34
defrost 10:e8b66718a103 35 // Set the GPIO Ports properly:
defrost 10:e8b66718a103 36 // PWM1 is connected to PA_8
defrost 10:e8b66718a103 37 // PWM1N is connected to PA_7
defrost 10:e8b66718a103 38
defrost 10:e8b66718a103 39 // Set the PWM outputs to general output pins:
defrost 10:e8b66718a103 40 // This sets the PA_7 and PA_8 pins to Alternate Function Pins
defrost 10:e8b66718a103 41 value = 0x8000 + 0x20000;
defrost 10:e8b66718a103 42 GPIOA->MODER |= value;
defrost 10:e8b66718a103 43
defrost 10:e8b66718a103 44 // Set the PWM outputs to high speed:
defrost 10:e8b66718a103 45 value = 0xC000 + 0x30000;
defrost 10:e8b66718a103 46 GPIOA->OSPEEDR |= value;
defrost 10:e8b66718a103 47
defrost 10:e8b66718a103 48 // Set PWM as outputs to the pins:
defrost 10:e8b66718a103 49 value = GPIOA->AFR[1];
defrost 10:e8b66718a103 50 // Reset the lowest four bits:
defrost 10:e8b66718a103 51 value &= 0xFFFFFFF0;
defrost 10:e8b66718a103 52 // Configure PA_8 to AF:
defrost 10:e8b66718a103 53 value |= 0x1;
defrost 10:e8b66718a103 54 GPIOA->AFR[1] = value;
defrost 10:e8b66718a103 55
defrost 10:e8b66718a103 56 value = GPIOA->AFR[0];
defrost 10:e8b66718a103 57 // Reset the the 4 MSB:
defrost 10:e8b66718a103 58 value &= 0x0FFFFFFF;
defrost 10:e8b66718a103 59 // Configure PA_7 to AF:
defrost 10:e8b66718a103 60 value |= 0x10000000;
defrost 10:e8b66718a103 61 GPIOA->AFR[0] = value;
defrost 10:e8b66718a103 62
defrost 10:e8b66718a103 63 // Set pull down resistors to PWM outputs:
defrost 10:e8b66718a103 64 value = GPIOA->PUPDR;
defrost 10:e8b66718a103 65 // Clear the bits:
defrost 10:e8b66718a103 66 value &= ~(GPIO_PUPDR_PUPDR7 | GPIO_PUPDR_PUPDR8);
defrost 10:e8b66718a103 67 // Set to pull down:
defrost 10:e8b66718a103 68 value |= GPIO_PUPDR_PUPDR7_1 | GPIO_PUPDR_PUPDR8_1;
defrost 10:e8b66718a103 69 // Set the register:
defrost 10:e8b66718a103 70 GPIOA ->PUPDR = value;
defrost 10:e8b66718a103 71
defrost 10:e8b66718a103 72 // Set the prescale value to 1:
defrost 10:e8b66718a103 73 TIM1->PSC = 0;
defrost 10:e8b66718a103 74
defrost 10:e8b66718a103 75 // *** TIM1 control register 1: TIMx_CR1 ***
defrost 10:e8b66718a103 76 value = 0;
defrost 10:e8b66718a103 77 // [9:8] Set CKD bits to zero for clock division of 1
defrost 10:e8b66718a103 78 // [7] TIMx_ARR register is buffered, set the ARPE bit to 1:
defrost 10:e8b66718a103 79 value |= TIM_CR1_ARPE;
defrost 10:e8b66718a103 80 // [6:5] Set CMS bits to zero for edge aligned mode
defrost 10:e8b66718a103 81 // [6:5] Set CMS bits to 10 for Center Aligned mode 2, up down mode with flags set when counter reaches the top.
defrost 10:e8b66718a103 82 //value |= TIM_CR1_CMS_1;
defrost 10:e8b66718a103 83 // [4] Set DIR bit to zero for upcounting
defrost 10:e8b66718a103 84 // [3] Set OPM bit to zero so that the counter is not stopped at update event
defrost 10:e8b66718a103 85 // [2] Set URS bit to zero so that anything can create an interrupt
defrost 10:e8b66718a103 86 // [1] Set UDIS bit to zero to generate an update event
defrost 10:e8b66718a103 87 // [0] Set the CEN bit to zero to disable the counter
defrost 10:e8b66718a103 88 // * Set the TIMx_CR1 Register: *
defrost 10:e8b66718a103 89 TIM1->CR1 |= value;
defrost 10:e8b66718a103 90
defrost 10:e8b66718a103 91 // *** TIM1 control register 2: TIMx_CR2 ***
defrost 10:e8b66718a103 92 value = 0;
defrost 10:e8b66718a103 93 // [14] Set OIS4 bit to zero, the idle state of OC4 output
defrost 10:e8b66718a103 94 // [13] Set OIS3N bit to zero, the idle state of OC3N output
defrost 10:e8b66718a103 95 // [12] Set OIS3 bit to zero, the idle state of OC3 output
defrost 10:e8b66718a103 96 // [11] Set OIS2N bit to zero, the idle state of OC2N output
defrost 10:e8b66718a103 97 // [10] Set OIS2 bit to zero, the idle state of OC2 output
defrost 10:e8b66718a103 98 // [9] Set OIS1N bit to zero, the idle state of OC1N output
defrost 10:e8b66718a103 99 // [8] Set OIS1 bit to zero, the idle state of OC1 output
defrost 10:e8b66718a103 100 // [7] Set TI1S bit to zero, connecting only CH1 pin to TI1 input
defrost 10:e8b66718a103 101 // [6:4] Set to 111: The OC4REF signal is used as trigger output (TRGO)
defrost 10:e8b66718a103 102 // value |= TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0;
defrost 10:e8b66718a103 103 //value |= TIM_CR2_MMS_1 | TIM_CR2_MMS_0;
defrost 10:e8b66718a103 104 // [3] Set CCDS bit to zero, request sent when CCx event occurs
defrost 10:e8b66718a103 105 // [2] Set CCUS bit to 1, capture/compare control bits are updated by setting the COMG bit or when a rising edge occurs on TRGI
defrost 10:e8b66718a103 106 //value |= 0x4;
defrost 10:e8b66718a103 107 // [0] Set CCPC bit to 1, CCxE, CCxNE and OCxM are update on a commutation event, or rising edge on TRGI
defrost 10:e8b66718a103 108 //value |= 0x1;
defrost 10:e8b66718a103 109 // * Set the TIMx_CR2 Register: *
defrost 10:e8b66718a103 110 TIM1->CR2 = value;
defrost 10:e8b66718a103 111
defrost 10:e8b66718a103 112 // *** TIM1 Auto Reload Register: ARR ***
defrost 10:e8b66718a103 113 value = 0;
defrost 10:e8b66718a103 114 // [15:0] Set ARR bits to the frequency to be loaded in:
defrost 10:e8b66718a103 115 newVal = ceil(period_us/PWMSTEP_US);
defrost 10:e8b66718a103 116 value = (unsigned int) newVal;
defrost 10:e8b66718a103 117 // * Set the TIMx_ARR Register:
defrost 10:e8b66718a103 118 TIM1->ARR = value;
defrost 10:e8b66718a103 119
defrost 10:e8b66718a103 120 // *** TIM1 capture/compare register 1: CCR1 ***
defrost 10:e8b66718a103 121 value = 0;
defrost 10:e8b66718a103 122 // [15:0] Set the capture compare value to the duty cycle:
defrost 10:e8b66718a103 123 newVal = ceil(duty_us/PWMSTEP_US);
defrost 10:e8b66718a103 124 value = (unsigned int) newVal;
defrost 10:e8b66718a103 125 // * Set the TIMx_CCR1 Register:
defrost 10:e8b66718a103 126 TIM1->CCR1 = value;
defrost 10:e8b66718a103 127
defrost 10:e8b66718a103 128 // *** TIM1 capture/compare register 4: CCR4 ***
defrost 10:e8b66718a103 129 value = 0;
defrost 10:e8b66718a103 130 // [15:0] Set the capture compare value to the value at which the PWM interrupt should be triggered:
defrost 10:e8b66718a103 131 newVal = 0;
defrost 10:e8b66718a103 132 value = (unsigned int) newVal;
defrost 10:e8b66718a103 133 // * Set the TIMx_CCR4 Register:
defrost 10:e8b66718a103 134 TIM1->CCR4 = 0;
defrost 10:e8b66718a103 135
defrost 10:e8b66718a103 136 // *** TIM1 capture/compare mode register 2: CCMR2
defrost 10:e8b66718a103 137 value = 0;
defrost 10:e8b66718a103 138 // [15] Set OC4CE bit to 0, OC4Ref is not affected by the ETRF input
defrost 10:e8b66718a103 139 // [14-12] Set the OC4M bits to '110', PWM mode 1, which is what we want I think.
defrost 10:e8b66718a103 140 value |= TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;
defrost 10:e8b66718a103 141 // [11] Set the OC4PE bit to 1, meaning read/write operations to the preload event require an update event.
defrost 10:e8b66718a103 142 value |= TIM_CCMR2_OC4PE;
defrost 10:e8b66718a103 143 // [10] Set the OC4FE bit to 0, the output compare fast enable is disabled
defrost 10:e8b66718a103 144 // [9:8] Set the CC4S bits to 0, the channel is configured as an output.
defrost 10:e8b66718a103 145 // * Set the TIMx_CCMR2 Register: *
defrost 10:e8b66718a103 146 TIM1->CCMR2 = value;
defrost 10:e8b66718a103 147
defrost 10:e8b66718a103 148 // *** TIM1 capture/compare mode register 1: CCMR1
defrost 10:e8b66718a103 149 value = 0;
defrost 10:e8b66718a103 150 // [7] Set OC1CE bit to 0, OC1Ref is not affected by the ETRF input
defrost 10:e8b66718a103 151 // [6-4] Set the OC1M bits to '110', PWM mode 1, which is what we want I think.
defrost 10:e8b66718a103 152 value |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
defrost 10:e8b66718a103 153 // [3] Set the OC1PE bit to 1, meaning read/write operations to the preload event require an update event.
defrost 10:e8b66718a103 154 value |= TIM_CCMR1_OC1PE;
defrost 10:e8b66718a103 155 // [2] Set the OC1FE bit to 0, the output compare fast enable is disabled
defrost 10:e8b66718a103 156 // [1:0] Set the CC1S bits to 0, the channel is configured as an output.
defrost 10:e8b66718a103 157 // * Set the TIMx_CCMR1 Register: *
defrost 10:e8b66718a103 158 TIM1->CCMR1 = value;
defrost 10:e8b66718a103 159
defrost 10:e8b66718a103 160 // *** TIM1 capture/compare enable register: CCER
defrost 10:e8b66718a103 161 value = 0;
defrost 10:e8b66718a103 162 // [15:4] - Don't care:
defrost 10:e8b66718a103 163 // [3] Set CC1NP bit to 1 for active low. (
defrost 10:e8b66718a103 164 value |= TIM_CCER_CC1NP;
defrost 10:e8b66718a103 165 // [2] Set CC1NE bit to 0, to de-activate the OC1N signal
defrost 10:e8b66718a103 166 // value |= 0x4;
defrost 10:e8b66718a103 167 // [1] Set the CC1P bit to 1 for active low.
defrost 10:e8b66718a103 168 value |= TIM_CCER_CC1P;
defrost 10:e8b66718a103 169 // [0] Set the CC1E bit to 1, to de-activate the OC1 signal
defrost 10:e8b66718a103 170 // value |= 0x1;
defrost 10:e8b66718a103 171 // * Set the TIM1_CCER Register: *
defrost 10:e8b66718a103 172 TIM1->CCER = value;
defrost 10:e8b66718a103 173
defrost 10:e8b66718a103 174 // *** TIM1 break and dead-time register: BDTR
defrost 10:e8b66718a103 175 value = 0;
defrost 10:e8b66718a103 176 // [15] Set MOE bit to 1 to enable the OC and OCN outputs
defrost 10:e8b66718a103 177 value |= 0x8000;
defrost 10:e8b66718a103 178 // [11] Set the OSSR bit such that the ouputs are forced to their idle mode when not running
defrost 10:e8b66718a103 179 //value |= TIM_BDTR_OSSR;
defrost 10:e8b66718a103 180 // [10] Set OSSI bit such that the outputs are forced to their idle mode when MOE = 0
defrost 10:e8b66718a103 181 value |= TIM_BDTR_OSSI;
defrost 10:e8b66718a103 182 // * Set the TIM1_BDTR register:
defrost 10:e8b66718a103 183 TIM1->BDTR = value;
defrost 10:e8b66718a103 184
defrost 10:e8b66718a103 185 // *** TIM1 DMA/Interrupt enable register: DIER
defrost 10:e8b66718a103 186 value = 0;
defrost 10:e8b66718a103 187 // [2] Set the CC1IE bit to 1, to trigger an interrupt when counter 1 has a match - which should be half way through the duty cycle.
defrost 10:e8b66718a103 188 value |= TIM_DIER_CC4IE;
defrost 10:e8b66718a103 189 // Set the TIM1_DIER register:
defrost 10:e8b66718a103 190 TIM1->DIER |= value;
defrost 10:e8b66718a103 191
defrost 10:e8b66718a103 192 // Set the UG bit in the EGR register to kick things off:
defrost 10:e8b66718a103 193 value = 3;
defrost 10:e8b66718a103 194 TIM1->EGR = value;
defrost 10:e8b66718a103 195
defrost 10:e8b66718a103 196 // Print a message saying you are done:
defrost 10:e8b66718a103 197 INFO("PWM configuration complete!");
defrost 10:e8b66718a103 198
defrost 10:e8b66718a103 199 #ifdef DEBUG_PWM
defrost 10:e8b66718a103 200 // Debugging Code:
defrost 10:e8b66718a103 201 DBG("TIM1 Registers:");
defrost 10:e8b66718a103 202 DBG("The CCMR1 Register reads: %d", TIM1->CCMR1);
defrost 10:e8b66718a103 203 DBG("The CR1 Register reads: %d", TIM1->CR1);
defrost 10:e8b66718a103 204 DBG("The CR2 Register reads: %d", TIM1->CR2);
defrost 10:e8b66718a103 205 DBG("The ARR Register reads: %d", TIM1->ARR);
defrost 10:e8b66718a103 206 DBG("The CCR1 Register reads: %d", TIM1->CCR1);
defrost 10:e8b66718a103 207 DBG("The CCER Register reads: %d", TIM1->CCER);
defrost 10:e8b66718a103 208 DBG("The BDTR Register reads: %d", TIM1->BDTR);
defrost 10:e8b66718a103 209 DBG("The EGR Register reads: %d", TIM1->EGR);
defrost 10:e8b66718a103 210 DBG("The SMCR Register reads: %d", TIM1->SMCR);
defrost 10:e8b66718a103 211 DBG("The PSC Register reads: %d", TIM1->PSC);
defrost 10:e8b66718a103 212 DBG("The GPIOA Registers:\n\r");
defrost 10:e8b66718a103 213 DBG("The MODER Register reads: %d", GPIOA->MODER);
defrost 10:e8b66718a103 214 DBG("The OSPEEDR Register reads: %d", GPIOA->OSPEEDR);
defrost 10:e8b66718a103 215 DBG("The AFR[0] Register reads: %d", GPIOA->AFR[0]);
defrost 10:e8b66718a103 216 DBG("The AFR[1] Register reads: %d", GPIOA->AFR[1]);
defrost 10:e8b66718a103 217 DBG("Clock Registers:");
defrost 10:e8b66718a103 218 DBG("The CFGR Register reads: %d", RCC->CFGR);
defrost 10:e8b66718a103 219
defrost 10:e8b66718a103 220 #endif
defrost 10:e8b66718a103 221
defrost 10:e8b66718a103 222 INFO("TIM1 Interrupt Priority: %d", NVIC_GetPriority(TIM1_CC_IRQn));
defrost 10:e8b66718a103 223 INFO("UART1 Interrupt Priority: %d", NVIC_GetPriority(USART1_IRQn));
defrost 10:e8b66718a103 224 INFO("UART2 Interrupt Priority: %d", NVIC_GetPriority(USART2_IRQn));
defrost 10:e8b66718a103 225 INFO("UART6 Interrupt Priority: %d", NVIC_GetPriority(USART6_IRQn));
defrost 10:e8b66718a103 226
defrost 10:e8b66718a103 227 // Configure the interrupt:
defrost 10:e8b66718a103 228 NVIC_SetVector(TIM1_CC_IRQn, (uint32_t)&TIM1_CC_IRQHandler);
defrost 10:e8b66718a103 229 NVIC_SetPriority(TIM1_CC_IRQn, PWMHIGHPRIORITY);
defrost 10:e8b66718a103 230 NVIC_EnableIRQ(TIM1_CC_IRQn);
defrost 10:e8b66718a103 231
defrost 10:e8b66718a103 232
defrost 10:e8b66718a103 233
defrost 10:e8b66718a103 234 return;
defrost 10:e8b66718a103 235 }
defrost 10:e8b66718a103 236
defrost 10:e8b66718a103 237 void TIM1_CC_IRQHandler(void){
defrost 10:e8b66718a103 238
defrost 10:e8b66718a103 239 // States of the PWM module:
defrost 10:e8b66718a103 240 /*
defrost 10:e8b66718a103 241 #define PWMST_SETUPCONV 0
defrost 10:e8b66718a103 242 #define PWMST_STARTCONV 1
defrost 10:e8b66718a103 243 #define PWMST_RUNSCSKDC 2
defrost 10:e8b66718a103 244 #define PWMST_CALCNEWPH 3
defrost 10:e8b66718a103 245 #define PWMST_SETNEWPH 4
defrost 10:e8b66718a103 246 #define PWMST_SHIFT 5
defrost 10:e8b66718a103 247 #define PWMST_SAMPLECHTROUGH 6
defrost 10:e8b66718a103 248 #define PWMST_WAITSAMPLETROUGH 7
defrost 10:e8b66718a103 249 #define PWMST_WAIT 8
defrost 10:e8b66718a103 250 #define PWMST_SAMPLECHHILL 9
defrost 10:e8b66718a103 251 #define PWMST_WAITSAMPLEHILL 10
defrost 10:e8b66718a103 252 #define PWMST_MAXST 11
defrost 10:e8b66718a103 253 */
defrost 10:e8b66718a103 254
defrost 10:e8b66718a103 255 if(((TIM1->SR & TIM_SR_CC4IF) > 0)&&(IotStatus.CheckFlag(SS_PWMOVERRUNFLAG) == false)){
defrost 10:e8b66718a103 256 // Block any other interrupts from occuring:
defrost 10:e8b66718a103 257 IotStatus.SetFlag(SS_PWMOVERRUNFLAG);
defrost 10:e8b66718a103 258
defrost 10:e8b66718a103 259 db = 1;
defrost 10:e8b66718a103 260
defrost 10:e8b66718a103 261 // Sample the ADCs:
defrost 10:e8b66718a103 262 VoltageMeasurement = VoltageSensor.read();
defrost 10:e8b66718a103 263 CurrentMeasurement = CurrentSensor.read();
defrost 10:e8b66718a103 264 db = 0;
defrost 10:e8b66718a103 265 // Set battery model inputs:
defrost 10:e8b66718a103 266
defrost 10:e8b66718a103 267
defrost 10:e8b66718a103 268 // Set a debug pin high:
defrost 10:e8b66718a103 269 db = 1; // Probe this pin to see how long the battery model algorithm takes to run.
defrost 10:e8b66718a103 270
defrost 10:e8b66718a103 271 // Run battery model here:
defrost 10:e8b66718a103 272
defrost 10:e8b66718a103 273
defrost 10:e8b66718a103 274 // Clear the debug pin:
defrost 10:e8b66718a103 275 db = 0;
defrost 10:e8b66718a103 276
defrost 10:e8b66718a103 277 // Read battery model outputs:
defrost 10:e8b66718a103 278
defrost 10:e8b66718a103 279
defrost 10:e8b66718a103 280
defrost 10:e8b66718a103 281 // Clear the flag:
defrost 10:e8b66718a103 282 IotStatus.ClearFlag(SS_PWMOVERRUNFLAG);
defrost 10:e8b66718a103 283 TIM1->SR &= (~TIM_SR_CC4IF);
defrost 10:e8b66718a103 284 }
defrost 10:e8b66718a103 285
defrost 10:e8b66718a103 286
defrost 10:e8b66718a103 287 return;
defrost 10:e8b66718a103 288 }
defrost 10:e8b66718a103 289
defrost 10:e8b66718a103 290
defrost 10:e8b66718a103 291
defrost 10:e8b66718a103 292
defrost 10:e8b66718a103 293
defrost 10:e8b66718a103 294 // Set a new duty cycle:
defrost 10:e8b66718a103 295 float SetDuty_us(float duty_us){
defrost 10:e8b66718a103 296 unsigned int value;
defrost 10:e8b66718a103 297 float newVal;
defrost 10:e8b66718a103 298 float temp = (duty_us/PwmPeriod_us);
defrost 10:e8b66718a103 299
defrost 10:e8b66718a103 300 newVal = ceil(duty_us/PWMSTEP_US);
defrost 10:e8b66718a103 301 value = (unsigned int) newVal;
defrost 10:e8b66718a103 302 // Disable the Update Event:
defrost 10:e8b66718a103 303 SETUDIS;
defrost 10:e8b66718a103 304 // * Set the TIMx_CCR1 Register:
defrost 10:e8b66718a103 305 TIM1->CCR1 = value;
defrost 10:e8b66718a103 306 // Set the CCR4 Register to the maximum value minus CH4SHIFT. This ensures the high speed ADC is in sync with the PWM module.
defrost 10:e8b66718a103 307 TIM1->CCR4 = 0;
defrost 10:e8b66718a103 308 // Re-enable the update event
defrost 10:e8b66718a103 309 CLEARUDIS;
defrost 10:e8b66718a103 310 return temp*PwmPeriod_us;
defrost 10:e8b66718a103 311 }
defrost 10:e8b66718a103 312
defrost 10:e8b66718a103 313
defrost 10:e8b66718a103 314 // Turns on and off the PWM:
defrost 10:e8b66718a103 315 void TurnOnPWM(bool trueForOn){
defrost 10:e8b66718a103 316 if(trueForOn){
defrost 10:e8b66718a103 317 // Enable the outputs:
defrost 10:e8b66718a103 318 DBG("Enabling outputs...");
defrost 10:e8b66718a103 319 TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE;
defrost 10:e8b66718a103 320 // Turn on the gating:
defrost 10:e8b66718a103 321 DBG("Turning on gating...:");
defrost 10:e8b66718a103 322 TIM1->CR1 |= TIM_CR1_CEN;
defrost 10:e8b66718a103 323 DBG("PWM on.");
defrost 10:e8b66718a103 324
defrost 10:e8b66718a103 325 }else{
defrost 10:e8b66718a103 326 // Turn off the gating:
defrost 10:e8b66718a103 327 TIM1->CR1 &= ~TIM_CR1_CEN;
defrost 10:e8b66718a103 328 // Disable the outputs:
defrost 10:e8b66718a103 329 TIM1->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1NE);
defrost 10:e8b66718a103 330 }
defrost 10:e8b66718a103 331 return;
defrost 10:e8b66718a103 332 }
defrost 10:e8b66718a103 333
defrost 10:e8b66718a103 334
defrost 10:e8b66718a103 335
defrost 10:e8b66718a103 336 void SetPWMPeriodAndDuty(int pwmper){
defrost 10:e8b66718a103 337 // This functions sets the PWM period by first disabling updates to the PWM module
defrost 10:e8b66718a103 338 // It also scales the duty cycle register, so the duty cycle is the SAME.
defrost 10:e8b66718a103 339
defrost 10:e8b66718a103 340 // Disable the UEV event in the PWM module:
defrost 10:e8b66718a103 341 SETUDIS;
defrost 10:e8b66718a103 342 // Set the new period:
defrost 10:e8b66718a103 343 TIM1->ARR = (unsigned int)(PwmPeriod_us/PWMSTEP_US);
defrost 10:e8b66718a103 344 // Set the new duty cycle:
defrost 10:e8b66718a103 345 TIM1->CCR1 = ((unsigned int)(Duty_us/PwmPeriod_us * TIM1->ARR));
defrost 10:e8b66718a103 346 // Set the CCR4 Register to the maximum value minus CH4SHIFT. This ensures the high speed ADC is in sync with the PWM module.
defrost 10:e8b66718a103 347 TIM1->CCR4 = 0;
defrost 10:e8b66718a103 348 // Re-enable the UEV event:
defrost 10:e8b66718a103 349 CLEARUDIS;
defrost 10:e8b66718a103 350 // Done!
defrost 10:e8b66718a103 351 return;
defrost 10:e8b66718a103 352 }
defrost 10:e8b66718a103 353
defrost 10:e8b66718a103 354 void SetPWMPeriodAndDuty_us(float period){
defrost 10:e8b66718a103 355 // This functions sets the PWM period by first disabling updates to the PWM module
defrost 10:e8b66718a103 356 // It also scales the duty cycle register, so the duty cycle is the SAME.
defrost 10:e8b66718a103 357 float PwmSteps = ((float)period/(float)PWMSTEP_US);
defrost 10:e8b66718a103 358
defrost 10:e8b66718a103 359 // Disable the UEV event in the PWM module:
defrost 10:e8b66718a103 360 SETUDIS;
defrost 10:e8b66718a103 361 // Set the new period:
defrost 10:e8b66718a103 362 if(PwmSteps > PWMARRMAX){
defrost 10:e8b66718a103 363 PwmSteps = PWMARRMAX;
defrost 10:e8b66718a103 364 WARN("Maximum PWM Period Reached.");
defrost 10:e8b66718a103 365 }
defrost 10:e8b66718a103 366 TIM1->ARR = (unsigned int)(PwmSteps);
defrost 10:e8b66718a103 367 DBG("TIM1->ARR: %d", TIM1->ARR);
defrost 10:e8b66718a103 368 DBG("period: %.3f", period);
defrost 10:e8b66718a103 369 DBG("PWMSTEP: %.3f", (float) PWMSTEP_US);
defrost 10:e8b66718a103 370 // Set the new duty cycle:
defrost 10:e8b66718a103 371 TIM1->CCR1 = ((unsigned int)(Duty_us/period * TIM1->ARR));
defrost 10:e8b66718a103 372 // Set the CCR4 Register to the maximum value minus CH4SHIFT. This ensures the high speed ADC is in sync with the PWM module.
defrost 10:e8b66718a103 373 TIM1->CCR4 = 0;
defrost 10:e8b66718a103 374 // Re-enable the UEV event:
defrost 10:e8b66718a103 375 CLEARUDIS;
defrost 10:e8b66718a103 376 // Done!
defrost 10:e8b66718a103 377 return;
defrost 10:e8b66718a103 378 }
defrost 10:e8b66718a103 379
defrost 10:e8b66718a103 380