elec350

Dependencies:   mbed

Fork of elec350 by Bob Merrison-Hort

microphone.cpp

Committer:
rmerrisonhort
Date:
2015-10-21
Revision:
12:ae626e46b996
Parent:
9:3801e1da153b
Child:
14:b1f94dd4a47f

File content as of revision 12:ae626e46b996:

#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 == false) {
        // 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;
    }
}

void Microphone::stop() // Not tested!
{
    // 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;
}

int8_t Microphone::read()
{
    return (int8_t)((uint16_t)_mic_pulses_buffered - 128);
}