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:
Sat Oct 25 03:28:55 2014 +0000
Revision:
17:c9ce210f6654
Parent:
13:fbd9b3f5a07c
Parth's edits for 10/24/14, items remaining: DC-DC, XBee, reading AMS/IMD error, main code

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