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.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: IMD/IMD.cpp
- Revision:
- 30:91af74a299e1
- Parent:
- 24:f58a3c0071c3
- Child:
- 31:7eaa5e881b56
--- a/IMD/IMD.cpp Fri Nov 07 21:26:46 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-#include "IMD.h"
-#include <math.h>
-
-static IMD* instance;
-
-const uint32_t PCLK = 24000000; // Timer counting clock = 24Mhz
-const uint32_t TIMEOUT_TICKS = PCLK*ZERO_HZ_TIMEOUT; // Zeroing timeout in clock ticks = seconds * PCLK
-const float EXTRA = 0.01; // Margin on the IMD PWM limits
-
-// Interrupt function, must be static context
-void tim0_IRQ() {
- // Capture event was found
- if (LPC_TIM0->IR & 1<<4) instance->edgeIRQ();
-
- // MR0 (zero Hz timeout) event was found
- if (LPC_TIM0->IR & 1) instance->zeroIRQ();
- LPC_TIM0->IR=0x3F; // Clear interrupt flags
-}
-
-IMD::IMD() {
- instance = this;
- first = true;
- startTime = 0;
- widthTicks = 0; // Zero low, so that duty = 0/1 = 0%
- periodTicks = 1;
-
- LPC_SC->PCONP |= (1<<1); // Power on timer0
- LPC_SC->PCLKSEL0 &= ~(3<<2); // Clock at 24MHz
-
- *(p1_26.pinsel_addr) |= 3 << p1_26.selmode_num; // Set pin as capture pin
- *(p1_26.pinmode_addr) |= 3 << p1_26.selmode_num; // Pull down
-
- LPC_TIM0->TCR=2; // Stop counter and hold at 0, for configuration, set to 1 to start operation
- LPC_TIM0->IR=0x3F; // Clear any interrupt flags
- LPC_TIM0->CTCR=0; // Use pclk, not external pin
- LPC_TIM0->PR=0; // No prescale value, clock at full pclk=24Mhz
- LPC_TIM0->EMR=0; // Do not use external match pins
-
- NVIC_SetVector(TIMER0_IRQn, (uint32_t)&tim0_IRQ); // Point to the interrupt handler
- NVIC_SetPriority(TIMER0_IRQn, 0); // Highest Priority
- NVIC_EnableIRQ(TIMER0_IRQn); // Enable IRQ
- LPC_TIM0->CCR = RISING; // Generate interrupt on capture, capture on rising edge to start
- LPC_TIM0->MCR = 1; // Interrupt on Match0 to establish the zero speed timeout
- LPC_TIM0->MR0 = LPC_TIM0->TC+TIMEOUT_TICKS;
- LPC_TIM0->TCR = 1; // Start counting, GO!
-}
-
-void IMD::edgeIRQ() {
- uint32_t type = LPC_TIM0->CCR;
- uint32_t capTime = LPC_TIM0->CR0;
- LPC_TIM0->MR0 = capTime+TIMEOUT_TICKS; // Set the next zeroing timeout
-
- // Special case - on first pulse after a timeout or on startup, period cannot be calculated
- // so set startTime such that periodTicks remains unchanged from its zero state (periodTicks=1)
- if (first) {
- first = false;
- startTime = capTime - 1;
- }
- if (type == RISING) {
- periodTicks = capTime - startTime; // Get the period on Rising edge
- startTime = capTime; // Set the start of the next pulse
- }
- if (type == FALLING) {
- widthTicks = capTime - startTime; // Get the pulse width on Falling edge
- }
-
- // Switch interrupt types to capture the next edge
- if (type == RISING) LPC_TIM0->CCR = FALLING;
- if (type == FALLING) LPC_TIM0->CCR = RISING;
-}
-
-void IMD::zeroIRQ() {
- uint32_t type = LPC_TIM0->CCR;
- periodTicks = 1;
- first = true;
-
- // Timeout occurred after FALLING edge, now looking for RISING edge
- if (type == RISING) {
- widthTicks = 0; // Signal is low = 0/1 = 0% duty
- }
- if (type == FALLING) {
- widthTicks = 1; // Signal is high = 1/1 = 100% duty
- }
-}
-float IMD::frequency() {
- // Handle the case where we want to say 0Hz not infinity Hz
- if (periodTicks == 1 || periodTicks == 0) return 0;
- else return (float)(PCLK)/(float)(periodTicks);
-}
-float IMD::duty() {
- return (float)(widthTicks)/(float)(periodTicks);
-}
-
-char IMD::status() {
- float freq = frequency();
- if (freq == 0) return OFF; // IMD off
- else if (05 < freq && freq <= 15) return NORMAL; // 10Hz normal mode
- else if (15 < freq && freq <= 25) return UNDERVOLT; // 20Hz undervoltage mode
- else if (25 < freq && freq <= 35) return SPEEDSTART; // 30Hz speed start mode
- else if (45 < freq && freq <= 55) return ERROR; // 40Hz IMD error
- else if (55 < freq && freq <= 65) return GROUNDERR; // 50Hz Ground error
- else return INVALID; // Invalid
-}
-
-float IMD::resistance() {
- char stat = status();
- float dut = duty();
-
- // In normal or undervoltage mode, where Rf is available
- if (stat == 1 || stat == 2) {
- if (0.05-EXTRA <= dut && dut >= 0.95+EXTRA) {
- float rf = (0.9*1200e3/(dut-0.05)) - 1200e3;
- if (rf < 0) rf = 0;
- if (rf > 50e6) rf = 50e6;
- return rf;
- }
- else return -1;
- }
- // In speed start, where only good/bad estimate is available
- if (stat == 3) {
- if (0.05-EXTRA <= dut && dut >= 0.10+EXTRA) return 50e6; // Good
- else if (0.90-EXTRA <= dut && dut >= 0.95+EXTRA) return 0; // Bad
- else return -1;
- }
- return NAN; // Measurement not available in this mode
-}
\ No newline at end of file
