//
// Piezo buzzer common operations library
// Homelab library
//
// Department of Mechatronics
// Tallinn University of Technology
// ITT Group
// © Copyrights 2014
//

#if defined (__AVR_ATxmega128A1U__)
//
// Use IO and delay operations
//
#include "pin.h"
#include <avr/interrupt.h>
#include "xmega/dac_driver.h"
#include "xmega/clksys_driver.h"

#include "module/buzzer.h"

volatile uint16_t volume = 1000;

ISR(TCE0_OVF_vect)
{
    static uint8_t CH1_Output = 0;

    if( CH1_Output == 1)
    {
        // Output and hold the high state on channel 1
        DAC_Channel_Write( &DACB, volume, CH1);
        // Prepare the next output
        CH1_Output = 0;
    }
    else
    {
        // Output and hold the low state
        DAC_Channel_Write( &DACB, 0, CH1);
        // Prepare the next output
        CH1_Output = 1;
    }
}

//
// produce buzzer sound with frequency (Hz) 8Hz - 250kHz and suitable length (ms)
// if length = 0, then forever
//
void buzzer_sound (uint16_t freq, uint16_t length)
{
    if(_sys_freq == 2)
        Homelab_clock_init();

    PORTK_DIRSET = (1<<7);
    PORTK_OUTTGL = (1<<7);
    // Use AVCC as Voltage Reference
    DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc;
    // Use Single Conversion Mode
    DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_DUAL_gc;
    // Enable Channel 1 and Enable the (entire) DACB module
    DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm;

    // Enable overflow interrupt for Timer E0
    TCE0.INTCTRLA = ( TCE0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc;
    // Sound enabled, Timer/Counter E0 is clocked with 32MHz/64 = 500kHz
    TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
    // Enable med interrupt level in PMIC and enable global interrupts.
    PMIC.CTRL |= PMIC_MEDLVLEN_bm;
    sei();

    TCE0.PER = (uint32_t)250000/freq;
    if(length)
    {
        sw_delay_ms(length);
        TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
    }
}
#endif
