/* * 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;