my library for elec350

Dependencies:   mbed

Revision:
3:d62097c19a4e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microphone.cpp	Wed Oct 19 20:33:20 2016 +0000
@@ -0,0 +1,99 @@
+#include "Microphone.h"
+
+bool _mic_toggle = false;
+uint8_t _mic_pulses= 0;
+uint8_t _mic_pulses_buffered = 0;
+uint8_t _mic_counter = 0;
+DigitalIn* _mic_d;
+DigitalOut* _mic_clk;
+
+void _mic_timer_int()
+{
+    // If clock output to mic is low, read data pin and increment
+    // pulse count if it's high.
+    if (!_mic_toggle) {
+        _mic_counter += 1;
+        if (_mic_counter == 0) {
+            _mic_pulses_buffered = _mic_pulses;
+            _mic_pulses = 0;
+        }
+        if (_mic_d->read()) _mic_pulses++;
+    }
+    
+    // Toggle clock output to mic
+    _mic_toggle = !_mic_toggle;
+    _mic_clk->write(_mic_toggle);
+    
+    // Clear interrupt
+    TIM3->SR &= ~TIM_SR_UIF;
+}
+
+Microphone::Microphone()
+{
+    this->isStarted = false;
+}
+
+void Microphone::start()
+{
+    if (!this->isStarted) {
+        // Two pins: clock to microphone and data from microphone.
+        _mic_d = new DigitalIn(PC_3);
+        _mic_clk = new DigitalOut(PB_10);
+        
+        // Use timer 3 to sample from the MP45DT02 microphone.
+        
+        // Enable timer.
+        RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
+        
+        // Scale timer so ticks are 100ns
+        uint32_t PCLK = SystemCoreClock / 4;
+        uint32_t prescale = PCLK / 10000000; // 10Mhz (100ns ticks)
+        TIM3->PSC = prescale - 1;
+        
+        // Enable counter
+        TIM3->CR1 |= TIM_CR1_CEN;
+    
+        // Set auto-reset after five ticks (500ns).
+        TIM3->ARR = 4;
+        
+        // Re-initialize counter.
+        TIM3->EGR |= TIM_EGR_UG;
+
+        // Set up and enable interrupt for when timer overflows.
+        NVIC_SetVector(TIM3_IRQn, (uint32_t)_mic_timer_int);
+        NVIC_EnableIRQ(TIM3_IRQn);
+        TIM3->DIER |= TIM_DIER_UIE;
+        this->isStarted = true;
+    }
+}
+
+void Microphone::stop() // Not tested!
+{
+    if (this->isStarted) {
+        // Disable interrupts.
+        NVIC_SetVector(TIM3_IRQn, (uint32_t)_mic_timer_int);
+        NVIC_DisableIRQ(TIM3_IRQn);
+        TIM3->DIER &= ~TIM_DIER_UIE;
+            
+        // Disable counter
+        TIM3->CR1 &= ~TIM_CR1_CEN;    
+            
+        // Disable timer.
+        RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
+            
+        // Clear interrupt
+        TIM3->SR &= ~TIM_SR_UIF;
+        
+        delete _mic_d; _mic_d = NULL;
+        delete _mic_clk; _mic_clk = NULL;
+    }
+}
+
+signed char Microphone::read()
+{
+    if (this->isStarted) {
+        return (int8_t)((uint16_t)_mic_pulses_buffered - 128);
+    } else {
+        return 0;
+    }
+}