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