Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Committer:
pspatel321
Date:
Fri Oct 24 22:09:04 2014 +0000
Revision:
13:fbd9b3f5a07c
Child:
17:c9ce210f6654
Fork showing Parth's changes to current monitor, IMD, and fanpump.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 13:fbd9b3f5a07c 1 #include "IMD.h"
pspatel321 13:fbd9b3f5a07c 2 #include <math.h>
pspatel321 13:fbd9b3f5a07c 3
pspatel321 13:fbd9b3f5a07c 4 static IMD* instance;
pspatel321 13:fbd9b3f5a07c 5
pspatel321 13:fbd9b3f5a07c 6 const uint32_t PCLK = 24000000; // Timer counting clock = 24Mhz
pspatel321 13:fbd9b3f5a07c 7 const uint32_t TIMEOUT_TICKS = PCLK*ZERO_HZ_TIMEOUT; // Zeroing timeout in clock ticks = seconds * PCLK
pspatel321 13:fbd9b3f5a07c 8 const float EXTRA = 0.01; // Margin on the IMD PWM limits
pspatel321 13:fbd9b3f5a07c 9 const float ULIM = 50000000; // Max value produced by IMD
pspatel321 13:fbd9b3f5a07c 10
pspatel321 13:fbd9b3f5a07c 11 // Interrupt function, must be static context
pspatel321 13:fbd9b3f5a07c 12 void TIM0_IRQ() {
pspatel321 13:fbd9b3f5a07c 13 // Capture event was found
pspatel321 13:fbd9b3f5a07c 14 if (LPC_TIM0->IR & 1<<4) instance->edgeIRQ();
pspatel321 13:fbd9b3f5a07c 15
pspatel321 13:fbd9b3f5a07c 16 // MR0 (zero Hz timeout) event was found
pspatel321 13:fbd9b3f5a07c 17 if (LPC_TIM0->IR & 1) instance->zeroIRQ();
pspatel321 13:fbd9b3f5a07c 18 LPC_TIM0->IR=0x3F; // Clear interrupt flags
pspatel321 13:fbd9b3f5a07c 19 }
pspatel321 13:fbd9b3f5a07c 20
pspatel321 13:fbd9b3f5a07c 21 IMD::IMD() {
pspatel321 13:fbd9b3f5a07c 22 instance = this;
pspatel321 13:fbd9b3f5a07c 23 first = true;
pspatel321 13:fbd9b3f5a07c 24 startTime = 0;
pspatel321 13:fbd9b3f5a07c 25 widthTicks = 0; // Zero low, so that duty = 0/1 = 0%
pspatel321 13:fbd9b3f5a07c 26 periodTicks = 1;
pspatel321 13:fbd9b3f5a07c 27
pspatel321 13:fbd9b3f5a07c 28 LPC_SC->PCONP |= (1<<2); // Power on timer1
pspatel321 13:fbd9b3f5a07c 29 LPC_SC->PCLKSEL0 &= ~(3<<4); // Clock at 24MHz
pspatel321 13:fbd9b3f5a07c 30
pspatel321 13:fbd9b3f5a07c 31 *(p1_26.pinsel_addr) |= 3 << p1_26.selmode_num; // Set pin as capture pin
pspatel321 13:fbd9b3f5a07c 32 *(p1_26.pinmode_addr) |= (3 << p1_26.selmode_num); // Pull down
pspatel321 13:fbd9b3f5a07c 33
pspatel321 13:fbd9b3f5a07c 34 LPC_TIM0->TCR=2; // Stop counter and hold at 0, for configuration, set to 1 to start operation
pspatel321 13:fbd9b3f5a07c 35 LPC_TIM0->IR=0x3F; // Clear any interrupt flags
pspatel321 13:fbd9b3f5a07c 36 LPC_TIM0->CTCR=0; // Use pclk, not external pin
pspatel321 13:fbd9b3f5a07c 37 LPC_TIM0->PR=0; // No prescale value, clock at full pclk=24Mhz
pspatel321 13:fbd9b3f5a07c 38 LPC_TIM0->EMR=0; // Do not use external match pins
pspatel321 13:fbd9b3f5a07c 39
pspatel321 13:fbd9b3f5a07c 40 NVIC_SetVector(TIMER1_IRQn, (uint32_t)&TIM0_IRQ); // Point to the edge interrupt handler
pspatel321 13:fbd9b3f5a07c 41 NVIC_SetPrioriry(TIMER1_IRQn, 0); // Highest Priority
pspatel321 13:fbd9b3f5a07c 42 NVIC_EnableIRQ(TIMER1_IRQn); // Enable IRQ
pspatel321 13:fbd9b3f5a07c 43 LPC_TIM0->CCR = RISING; // Generate interrupt on capture, capture on rising edge to start
pspatel321 13:fbd9b3f5a07c 44 LPC_TIM0->MCR = 1; // Interrupt on Match0 to establish the zero speed timeout
pspatel321 13:fbd9b3f5a07c 45 LPC_TIM0->MR0 = LPC_TIM0->TC+TIMEOUT_TICKS;
pspatel321 13:fbd9b3f5a07c 46 LPC_TIM0->TCR = 1; // Start counting, GO!
pspatel321 13:fbd9b3f5a07c 47 }
pspatel321 13:fbd9b3f5a07c 48
pspatel321 13:fbd9b3f5a07c 49 void IMD::edgeIRQ() {
pspatel321 13:fbd9b3f5a07c 50 enum EdgeT type = LPC_TIM0->CCR;
pspatel321 13:fbd9b3f5a07c 51 uint32_t capTime = LPC_TIM0->CR0;
pspatel321 13:fbd9b3f5a07c 52 LPC_TIM0->MR0 = capTime+TIMEOUT_TICKS; // Set the next zeroing timeout
pspatel321 13:fbd9b3f5a07c 53
pspatel321 13:fbd9b3f5a07c 54 // Special case - on first pulse after a timeout or on startup, period cannot be calculated
pspatel321 13:fbd9b3f5a07c 55 // so set startTime such that periodTicks remains unchanged from its zero state (periodTicks=1)
pspatel321 13:fbd9b3f5a07c 56 if (first) {
pspatel321 13:fbd9b3f5a07c 57 first = false;
pspatel321 13:fbd9b3f5a07c 58 startTime = capTime - 1;
pspatel321 13:fbd9b3f5a07c 59 }
pspatel321 13:fbd9b3f5a07c 60 if (type == RISING) {
pspatel321 13:fbd9b3f5a07c 61 periodTicks = capTime - startTime; // Get the period on Rising edge
pspatel321 13:fbd9b3f5a07c 62 startTime = capTime; // Set the start of the next pulse
pspatel321 13:fbd9b3f5a07c 63 }
pspatel321 13:fbd9b3f5a07c 64 if (type == FALLING) {
pspatel321 13:fbd9b3f5a07c 65 widthTicks = capTime - startTime; // Get the pulse width on Falling edge
pspatel321 13:fbd9b3f5a07c 66 }
pspatel321 13:fbd9b3f5a07c 67
pspatel321 13:fbd9b3f5a07c 68 // Switch interrupt types to capture the next edge
pspatel321 13:fbd9b3f5a07c 69 if (type == RISING) LPC_TIM0->CCR = FALIING;
pspatel321 13:fbd9b3f5a07c 70 if (type == FALLING) LPC_TIM0->CCR = RISING;
pspatel321 13:fbd9b3f5a07c 71 }
pspatel321 13:fbd9b3f5a07c 72
pspatel321 13:fbd9b3f5a07c 73 void IMD::zeroIRQ() {
pspatel321 13:fbd9b3f5a07c 74 enum EdgeT type = LPC_TIM0->CCR;
pspatel321 13:fbd9b3f5a07c 75 periodTicks = 1;
pspatel321 13:fbd9b3f5a07c 76 first = true;
pspatel321 13:fbd9b3f5a07c 77
pspatel321 13:fbd9b3f5a07c 78 // Timeout occurred after FALLING edge, now looking for RISING edge
pspatel321 13:fbd9b3f5a07c 79 if (type == RISING) {
pspatel321 13:fbd9b3f5a07c 80 widthTicks = 0; // Signal is low = 0/1 = 0% duty
pspatel321 13:fbd9b3f5a07c 81 }
pspatel321 13:fbd9b3f5a07c 82 if (type == FALLING) {
pspatel321 13:fbd9b3f5a07c 83 widthTicks = 1; // Signal is high = 1/1 = 100% duty
pspatel321 13:fbd9b3f5a07c 84 }
pspatel321 13:fbd9b3f5a07c 85 }
pspatel321 13:fbd9b3f5a07c 86 float IMD::frequency() {
pspatel321 13:fbd9b3f5a07c 87 // Handle the case where we want to say 0Hz not infinity Hz
pspatel321 13:fbd9b3f5a07c 88 if (periodTicks == 1 || periodTicks == 0) return 0;
pspatel321 13:fbd9b3f5a07c 89 else return (float)(PCLK)/(float)(periodTicks);
pspatel321 13:fbd9b3f5a07c 90 }
pspatel321 13:fbd9b3f5a07c 91 float IMD::duty() {
pspatel321 13:fbd9b3f5a07c 92 return (float)(widthTicks)/(float)(periodTicks);
pspatel321 13:fbd9b3f5a07c 93 }
pspatel321 13:fbd9b3f5a07c 94
pspatel321 13:fbd9b3f5a07c 95 char IMD::status() {
pspatel321 13:fbd9b3f5a07c 96 float freq = frequency();
pspatel321 13:fbd9b3f5a07c 97 if (freq == 0) return 0; // IMD off
pspatel321 13:fbd9b3f5a07c 98 else if (05 < freq && freq <= 15) return 1; // 10Hz normal mode
pspatel321 13:fbd9b3f5a07c 99 else if (15 < freq && freq <= 25) return 2; // 20Hz undervoltage mode
pspatel321 13:fbd9b3f5a07c 100 else if (25 < freq && freq <= 35) return 3; // 30Hz speed start mode
pspatel321 13:fbd9b3f5a07c 101 else if (45 < freq && freq <= 55) return 4; // 40Hz IMD error
pspatel321 13:fbd9b3f5a07c 102 else if (55 < freq && freq <= 65) return 5; // 50Hz Ground error
pspatel321 13:fbd9b3f5a07c 103 else return -1; // Invalid
pspatel321 13:fbd9b3f5a07c 104 }
pspatel321 13:fbd9b3f5a07c 105
pspatel321 13:fbd9b3f5a07c 106 float IMD::resistance() {
pspatel321 13:fbd9b3f5a07c 107 char status = status();
pspatel321 13:fbd9b3f5a07c 108 float duty = duty();
pspatel321 13:fbd9b3f5a07c 109
pspatel321 13:fbd9b3f5a07c 110 // In normal or undervoltage mode, where Rf is available
pspatel321 13:fbd9b3f5a07c 111 if (status == 1 || status == 2) {
pspatel321 13:fbd9b3f5a07c 112 if (0.05-EXTRA <= duty && duty >= 0.95+EXTRA) {
pspatel321 13:fbd9b3f5a07c 113 float rf = (0.9*1200e3/(duty-0.05)) - 1200e3;
pspatel321 13:fbd9b3f5a07c 114 if (rf < 0) rf = 0;
pspatel321 13:fbd9b3f5a07c 115 if (rf > 50e6) rf = 50e6;
pspatel321 13:fbd9b3f5a07c 116 return rf;
pspatel321 13:fbd9b3f5a07c 117 }
pspatel321 13:fbd9b3f5a07c 118 else return -1;
pspatel321 13:fbd9b3f5a07c 119 }
pspatel321 13:fbd9b3f5a07c 120 // In speed start, where only good/bad estimate is available
pspatel321 13:fbd9b3f5a07c 121 if (status == 3) {
pspatel321 13:fbd9b3f5a07c 122 if (0.05-EXTRA <= duty && duty >= 0.10+EXTRA) return 50e6; // Good
pspatel321 13:fbd9b3f5a07c 123 else if (0.90-EXTRA <= duty && duty >= 0.95+EXTRA) return 0; // Bad
pspatel321 13:fbd9b3f5a07c 124 else return -1;
pspatel321 13:fbd9b3f5a07c 125 }
pspatel321 13:fbd9b3f5a07c 126 return NaN;
pspatel321 13:fbd9b3f5a07c 127 }