
/*
 * Copyright 2017-2024 Oleg Borodin <onborodin@gmail.com>
 */

#include <avr/interrupt.h>
#include <util/delay.h>

#include <tool.h>

void adc_init() {
    /* Disable ADC */
    REG_SETDOWN_BIT(ADCSRA, ADEN);
    /* Set reference*/
    REG_SETUP_BIT(ADMUX, REFS0);
    REG_SETDOWN_BIT(ADMUX, REFS1);
    /* Set result type */
    REG_SETUP_BIT(ADMUX, ADLAR);
    /* Set freq prescale */
    REG_SETUP_BIT(ADCSRA, ADPS2);
    REG_SETUP_BIT(ADCSRA, ADPS1);
    REG_SETUP_BIT(ADCSRA, ADPS0);
    /* Disable autoconversion */
    REG_SETDOWN_BIT(ADCSRA, ADATE);
    /* Disable interrupt */
    REG_SETDOWN_BIT(ADCSRA, ADIE);
    /* Enable ADC */
    REG_SETUP_BIT(ADCSRA, ADEN);
}

uint16_t adc_read(uint8_t channel) {
    uint8_t reg = ADMUX;
    ADMUX = (reg & 0xF0) | channel;
    REG_SETUP_BIT(ADCSRA, ADSC);
    while (ADCSRA & BIT(ADSC));
    uint16_t lval = (uint16_t)ADCL;
    uint16_t hval = (uint16_t)ADCH;
    hval = (hval << 8) & 0xFF00;
    lval = lval & 0x00FF;
    return (hval | lval);
}


