/* * Author: Jake G * Date: 2025 * filename: test_ADC.c * description: module_purpose */ #include "CppUTest/CommandLineTestRunner.h" #include "CppUTestExt/MockSupport.h" #include //This define allows us to dircetly include the device header without error. #define _AVR_IO_H_ extern "C" { #include "sfr_defs.h" #include //ATtiny13A header file. #include "ADC.h" } TEST_GROUP(test_ADC) { void setup() { } void teardown() { mock().checkExpectations(); mock().clear(); } }; TEST(test_ADC, FirstTest) { CHECK(true); } TEST(test_ADC, ADC_SetupSetsRegisters) { /* * ADC Channel Selection(MUX1, MUX0): * 00 == ADC0/PB5 * 01 == ADC1/PB2 * 10 == ADC2/PB4 * 11 == ADC3/PB3 */ /*Set the ADC Channel 0 (default) using ADMUX reg*/ /*Set the voltage reference to VCC.*/ /*Set ADC Left adjust result setting to off.*/ mock().expectOneCall("RegEdit_ClearRegister") .withPointerParameter("reg", (void *) &ADMUX); /*ADC0 Status and Control Register A*/ /*Set the Prescaler (F_CPU/8) for samping frequency.*/ mock().expectOneCall("RegEdit_SetNum") .withPointerParameter("reg", (void *) &ADCSRA) .withUnsignedIntParameter("num", 3); /*ADC0 Status and Control Register B*/ /*Setup the auto-trigger source.*/ /*Using timer compare/match B for now.*/ mock().expectOneCall("RegEdit_AND_Num") .withPointerParameter("reg", (void *) &ADCSRB) .withUnsignedIntParameter("num", 5); ADC_Setup(); } TEST(test_ADC, ADC_InitRejectsInvalidChannels) { for(uint8_t i = 4; i < 255; i++){ ADC_Init(i); } } TEST(test_ADC, ADC_InitPortbWorksWithValidChannels) { uint8_t pin_num; for(uint8_t adc_channel = 0; adc_channel <= 3; adc_channel++) { pin_num = ADC_GetChannelPinNum(adc_channel); //Check it disables the pin's digital circuitry //Check it sets the pin for input mock().expectOneCall("RegEdit_ClearBit") .withPointerParameter("reg", (void *) &DDRB) .withUnsignedIntParameter("bit_num", pin_num); //Check that the pull-up resistor is disabled. mock().expectOneCall("RegEdit_ClearBit") .withPointerParameter("reg", (void *) &PORTB) .withUnsignedIntParameter("bit_num", pin_num); //Check that the ADC pin is selected in ADMUX //Clears the last two bits first. mock().expectOneCall("RegEdit_AND_Num") .withPointerParameter("reg", (void *) &ADMUX) .withUnsignedIntParameter("num", 0xFC); //Selects the ADC pin/channel mock().expectOneCall("RegEdit_OR_Num") .withPointerParameter("reg", (void *) &ADMUX) .withUnsignedIntParameter("num", adc_channel); ADC_Init(adc_channel); } } TEST(test_ADC, ADC_EnablePasses) { mock().expectOneCall("RegEdit_SetBit") .withPointerParameter("reg", (void *) &ADCSRA) .withUnsignedIntParameter("bit_num", ADEN); ADC_Enable(); } TEST(test_ADC, ADC_DisablePasses) { mock().expectOneCall("RegEdit_ClearBit") .withPointerParameter("reg", (void *) &ADCSRA) .withUnsignedIntParameter("bit_num", ADEN); ADC_Disable(); } TEST(test_ADC, ADC_ReadValueImplimentationTimesOut) { //Expect the start conversion bit to be set. mock().expectOneCall("RegEdit_SetBit") .withPointerParameter("reg", (void *) &ADCSRA) .withUnsignedIntParameter("bit_num", ADSC); //Check that it can time out. //Expect it to read the start bit mock().expectNCalls(ADC_WAIT_TIMEOUT, "RegEdit_IsBitSet") .withPointerParameter("reg", (void *) &ADCSRA) .withUnsignedIntParameter("bit_num", ADSC); //Check that it does return a value. ADC_ReadValue(0); } static uint16_t ADC_ReadValueFake(uint8_t pin_num) { return 512; } TEST_GROUP(test_ADCReadPtrSwap) { void setup() { UT_PTR_SET(ADC_ReadValue, ADC_ReadValueFake); } void teardown() { } }; TEST(test_ADCReadPtrSwap, FunctionPointerSwapWorks) { uint16_t value = ADC_ReadValue(0); LONGS_EQUAL(512, value); }