fg004_a1/ADC.c

97 lines
2.1 KiB
C
Raw Normal View History

/*
* Author: username
* Date: 2024
* filename: ADC.c
* description: module_purpose
*/
#include "ADC.h"
#include "RegEdit.h"
#include "avr/io.h"
static bool IsInvalidPin(uint8_t pin_num){
if(pin_num > 7){
return true;
}
return false;
}
void ADC_Init(uint8_t pin_num)
{
if(IsInvalidPin(pin_num)){return;}
//set the direction to input
RegEdit_SetBit((void *) &PORTA.DIRCLR, pin_num);
//Disable the pull-up resistor
RegEdit_SetBit((void *) &PORTA.OUTCLR, 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.
//PORT_ISC_INPUT_DISABLE_gc
RegEdit_SetBit(
(void *) (&PORTA.PIN0CTRL)+pin_num,
PORT_ISC_INPUT_DISABLE_gc
);
/*
RegEdit_OR_Num(
(void *) (&PORTA.PIN0CTRL)+pin_num,
PORT_ISC_INPUT_DISABLE_gc
);*/
//Ensure we use full 10bit resolution
RegEdit_ClearBit((void *) &ADC0.CTRLA, 2);
//Use VDD as our voltage refernce.
RegEdit_SetBit((void *) &ADC0.CTRLC, 4);
}
void ADC_Enable(uint8_t pin_num)
{
if(IsInvalidPin(pin_num)){return;}
//Use muxpos to select pins for ADC to connect.
RegEdit_OR_Num((void *) &ADC0.MUXPOS, pin_num);
//Set the enable bit in the CTRLA register
RegEdit_SetBit((void *) &ADC0.CTRLA, 0);
}
void ADC_Disable()
{
//Set for no ADC connections.
RegEdit_ClearRegister((void *) &ADC0.MUXPOS);
//Clear the enable ADC flag
RegEdit_ClearBit((void *) &ADC0.CTRLA, 0);
}
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) )
//while(!(RegEdit_IsBitSet((void *) &ADC0.INTFLAGS, ADC_RESSEL_bm)))
while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
{
;
}
/* Clear the interrupt flag by writing 1: */
ADC0.INTFLAGS = ADC_RESRDY_bm;
return (uint16_t) ADC0.RES;
}
//Set the default for the function pointer.
uint16_t (*ADC_ReadValue)(uint8_t pin_num) = ADC_ReadValue_Impl;