my library for elec350

Dependencies:   mbed

microphone.cpp

Committer:
spanesar
Date:
2016-10-19
Revision:
3:d62097c19a4e

File content as of revision 3:d62097c19a4e:

#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;
    }
}