/* * rhmidi * * Copyright (C) 2014 Christian Pointner * * This file is part of rhmidi. * * rhmidi is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * rhmidi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rhmidi. If not, see . */ #include #include "analog.h" #include "eventqueue.h" #define ANALOG_PIN PINF #define ANALOG_PORT PORTF #define ANALOG_DDR DDRF #include static struct { uint8_t enabled; uint8_t last_sent; } analog_input_state[ANALOG_NUM_INPUTS]; static uint8_t analog_channels[] = { ADC_CHANNEL0, ADC_CHANNEL1, ADC_CHANNEL2, ADC_CHANNEL3, ADC_CHANNEL4, ADC_CHANNEL5, ADC_CHANNEL6, ADC_CHANNEL7 }; void analog_init(void) { ANALOG_DDR = 0x00; ANALOG_PORT = 0x00; int i; for(i = 0; i < ANALOG_NUM_INPUTS; ++i) { analog_input_state[i].enabled = 0; analog_input_state[i].last_sent = 0; } ADC_Init(ADC_SINGLE_CONVERSION | ADC_PRESCALE_32); } static void analog_channel_set_enabled(uint8_t channel, uint8_t enabled) { if(enabled) { ADC_SetupChannel(channel); analog_input_state[channel].enabled = 1; } else { ADC_DisableChannel(channel); analog_input_state[channel].enabled = 0; } } void analog_enable_channel(uint8_t channel) { if(channel < ANALOG_NUM_INPUTS) analog_channel_set_enabled(channel, 1); else if(channel == ANALOG_MIDI_NOTE_ALL_INPUTS - ANALOG_MIDI_NOTE_OFFSET) { int i; for(i = 0; i < ANALOG_NUM_INPUTS; ++i) analog_channel_set_enabled(i, 1); } } void analog_disable_channel(uint8_t channel) { if(channel < ANALOG_NUM_INPUTS) analog_channel_set_enabled(channel, 0); else if(channel == ANALOG_MIDI_NOTE_ALL_INPUTS - ANALOG_MIDI_NOTE_OFFSET) { int i; for(i = 0; i < ANALOG_NUM_INPUTS; ++i) analog_channel_set_enabled(i, 0); } } uint8_t analog_get_value(uint8_t channel) { if(channel >= ANALOG_NUM_INPUTS) return 0; return analog_input_state[channel].last_sent; } void analog_task(void) { uint8_t i; for(i = 0; i < ANALOG_NUM_INPUTS; ++i) { if(analog_input_state[i].enabled) { uint8_t tmp = (ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | analog_channels[i])) >> 3; if(analog_input_state[i].last_sent != tmp) { analog_input_state[i].last_sent = tmp; eventqueue_push(ANALOG_MIDI_NOTE_OFFSET + i, 0); } } } }