112 lines
2.3 KiB
C
112 lines
2.3 KiB
C
/*
|
|
* Author: username
|
|
* Date: 2024
|
|
* filename: ADC.c
|
|
* description: module_purpose
|
|
*/
|
|
|
|
#ifndef __AVR_ATtiny404__
|
|
#define __AVR_ATtiny404__
|
|
#endif
|
|
|
|
#include "ADC.h"
|
|
#include "RegEdit.h"
|
|
#include "avr/io.h"
|
|
|
|
#define MAX_PIN_NUM 7
|
|
|
|
static bool IsInvalidPin(uint8_t pin_num){
|
|
if(pin_num > MAX_PIN_NUM){
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void ADC_Setup(void)
|
|
{
|
|
//Clears control register A for ADC0
|
|
RegEdit_SetNum((void *) &ADC0.CTRLA, 0x00);
|
|
|
|
//Sets The sample accumulation number to 32.
|
|
RegEdit_SetNum((void *) &ADC0.CTRLB, 0x5);
|
|
|
|
//Sets the voltage reference to VDD or VCC.
|
|
RegEdit_SetBit((void *) &ADC0.CTRLC, 4);
|
|
|
|
//Sets the pre-scalar for the adc sample rate.
|
|
RegEdit_SetBit((void *) &ADC0.CTRLC, 2);
|
|
|
|
//Setup an Initalization delay.
|
|
RegEdit_OR_Num((void *) &ADC0.CTRLD, (2<<5));
|
|
|
|
//Set the bit for ADC variation during readings.
|
|
RegEdit_SetBit((void *) &ADC0.CTRLD, 4);
|
|
}
|
|
|
|
void ADC_Init(uint8_t pin_num)
|
|
{
|
|
|
|
if(IsInvalidPin(pin_num)){return;}
|
|
|
|
|
|
//set the direction to input
|
|
RegEdit_ClearBit((void *) &PORTA.DIR, pin_num);
|
|
|
|
//Disable the pull-up resistor
|
|
RegEdit_ClearBit((void *) &PORTA.OUT, pin_num);
|
|
|
|
//Disable input buffer
|
|
//We do some kinda nasty address addition but it saves
|
|
//memory and means we don't need a switch statment.
|
|
RegEdit_SetBit(
|
|
(void *) (&PORTA.PIN0CTRL)+pin_num,
|
|
PORT_ISC_INPUT_DISABLE_gc
|
|
);
|
|
|
|
}
|
|
|
|
|
|
void ADC_Enable(void)
|
|
{
|
|
//Set the enable bit in the CTRLA register
|
|
RegEdit_SetBit((void *) &ADC0.CTRLA, 0);
|
|
}
|
|
|
|
|
|
void ADC_Disable()
|
|
{
|
|
//Clear the enable ADC flag
|
|
RegEdit_ClearBit((void *) &ADC0.CTRLA, 0);
|
|
}
|
|
|
|
|
|
void ADC_SetPin(uint8_t pin_num)
|
|
{
|
|
if(IsInvalidPin(pin_num)){return;}
|
|
RegEdit_ClearRegister((void *) &ADC0.MUXPOS);
|
|
RegEdit_SetNum((void *) &ADC0.MUXPOS, pin_num);
|
|
}
|
|
|
|
|
|
uint16_t ADC_ReadValue_Impl(uint8_t pin_num)
|
|
{
|
|
RegEdit_SetNum((void *) &ADC0.COMMAND, ADC_STCONV_bm);
|
|
|
|
/* Wait until ADC conversion done */
|
|
while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
|
|
{
|
|
;
|
|
}
|
|
|
|
/* Clear the interrupt flag by writing 1: */
|
|
ADC0.INTFLAGS = ADC_RESRDY_bm;
|
|
|
|
uint16_t adc_val = (uint16_t) ADC0.RES;
|
|
adc_val = adc_val >> 5;
|
|
return adc_val;
|
|
}
|
|
|
|
|
|
//Set the default for the function pointer.
|
|
uint16_t (*ADC_ReadValue)(uint8_t pin_num) = ADC_ReadValue_Impl;
|