Compare commits

..

No commits in common. "main" and "v0.1.2" have entirely different histories.
main ... v0.1.2

46 changed files with 40 additions and 1778 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20)
# Use the fancy version substitution # Use the fancy version substitution
project(main project(main
VERSION 0.3.0 VERSION 0.1.2
DESCRIPTION "template for cmake + cpputest" DESCRIPTION "template for cmake + cpputest"
LANGUAGES C CXX LANGUAGES C CXX
) )
@ -38,7 +38,7 @@ set(CMAKE_CXX_FLAGS "-Wall -Werror -Wpedantic")
if (UNIT_TESTING) if (UNIT_TESTING)
add_definitions(-DUNIT_TESTING)
if(DEFINED ENV{CPPUTEST_HOME}) if(DEFINED ENV{CPPUTEST_HOME})
message(STATUS "Using CppUTest home: $ENV{CPPUTEST_HOME}") message(STATUS "Using CppUTest home: $ENV{CPPUTEST_HOME}")
set(CPPUTEST_INCLUDE_DIRS $ENV{CPPUTEST_HOME}/include) set(CPPUTEST_INCLUDE_DIRS $ENV{CPPUTEST_HOME}/include)
@ -71,7 +71,6 @@ include_directories(
./inc ./inc
/usr/local/avr/include/avr /usr/local/avr/include/avr
/usr/local/avr/include /usr/local/avr/include
/usr/local/avr/avr/include #for Linux
) )
add_subdirectory(src) add_subdirectory(src)

View File

@ -32,16 +32,6 @@ The position will now be saved into the EEPROM memory.
To automatically move the fader into the saved location preform a quick To automatically move the fader into the saved location preform a quick
press of the button. press of the button.
The speed can be adjusted by changing the input value of the speed pot. The
speed adjustment affects the on/off ratio of the motor and has a programmed
minimum speed value in the function to prevent endless looping.
### Move to secondary Position
When the motor has already preformed a move to position from a quick
button press, you can tap the button once more and it will go back to it's
previous position from your initial button press.
## Building Project(Windows) ## Building Project(Windows)

View File

@ -15,11 +15,9 @@ set(AVR_MCU attiny13a)
#set(AVR_MCU avr64dd28) # Newer DX series, avrxmega2 #set(AVR_MCU avr64dd28) # Newer DX series, avrxmega2
#set(F_CPU 16000000UL) #set(F_CPU 16000000UL)
#set(F_CPU 8000000UL) #set(F_CPU 8000000)
#set(F_CPU 9600000UL)#AVR without prescaler set(F_CPU 9600000)
set(F_CPU 1200000UL) #AVR (9.6MHz) with prescaler 8DIV #set(F_CPU 4800000)
#set(F_CPU 4800000UL) #AVR without prescaler
#set(F_CPU 600000UL) #AVR (4.8MHz) with prescaler 8DIV
add_compile_definitions(F_CPU=${F_CPU}) add_compile_definitions(F_CPU=${F_CPU})
# add_compile_definitions(MCU=atmega328p) # add_compile_definitions(MCU=atmega328p)

View File

@ -1,71 +0,0 @@
/**
* @brief Module/Interface for editing AVR registers
* @details This file is an interface to AVR registers or the avr/io.h
* @author Jake G
* @date 2024
* @copyright None
* @file RegEdit.h
*/
#ifndef REGEDIT_H
#define REGEDIT_H
#include <stdint.h>
#include <stdbool.h>
/**
* @brief Sets the value of the register to 0xFF.
* @param reg A pointer to a register
*/
void RegEdit_SetRegister(void *reg);
/**
* @brief Sets the value of the register to 0x00.
* @param reg A pointer to a register
*/
void RegEdit_ClearRegister(void *reg);
/**
* @brief Sets a single bit in the register.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
void RegEdit_SetBit(void *reg, uint8_t bit_num);
/**
* @brief Clears a single bit in the register.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
void RegEdit_ClearBit(void *reg, uint8_t bit_num);
/**
* @brief Checks if a single bit is set in the register.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
bool RegEdit_IsBitSet(void *reg, uint8_t bit_num);
/**
* @brief Preforms logical OR Equals with the passed num.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
void RegEdit_OR_Num(void *reg, uint8_t num);
/**
* @brief Preforms logical AND Equals with the passed num.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
void RegEdit_AND_Num(void *reg, uint8_t num);
/**
* @brief Sets the register to the passed number value.
* @param reg A pointer to a register
* @param The bit's index or number in the register
*/
void RegEdit_SetNum(void *reg, uint8_t num);
#endif //REGEDIT_H

View File

@ -1,60 +0,0 @@
/**
* @file config.h
* @author Jake G
* @date 15 June 2024
* @brief File contains the project configuration values
*
* This file contains the user changable parameters. Most the values are
* constants that will change the behavior of the system.
*
* For these changes to take affect you must recompile/rebuild the project
* after you have changed the values.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <stdint.h>
#define ADC_LOAD1 4
#define ADC_LOAD2 5
#define ADC_LOAD3 6
/**
* @brief Positive Zero Crossing Trigger Value
* The 10 bit value at which the program triggers the ISR to handle
* the zero crossing event.
*
* You can adjust this to change when the program will start the timer.
*/
const uint16_t TriggerValue = 512;
/**
* @brief Triac Gate Pulse Quantity
*
* Contains the number of pulses that the micro-controller will send to the
* gates of the triac.
*
* This number should match the quantity of timings inside the pulse/duration
* array.
*/
const int GatePulsesQty = 5;
/**
* @brief Gate Pulses Array
*
* The gate pulses array holds the duration of pulses in microseconds for the
* triacs gates. The length of the array must be matched with the
* GatePulsesQuantity parameter.
*/
const uint16_t GatePulses[5] = {250, 500, 750, 1000, 1250};
/**
* @brief The time constant.
*/
const double Tau = 8250;
#endif //CONFIG_H

View File

@ -10,10 +10,6 @@
#ifndef MAIN_H #ifndef MAIN_H
#define MAIN_H #define MAIN_H
#ifndef __AVR_ATtiny13A__
#define __AVR_ATtiny13A__
#endif
#include <avr/io.h> #include <avr/io.h>
@ -32,8 +28,8 @@
//Addresses in the eeprom for the two switch states //Addresses in the eeprom for the two switch states
#define ROM_SP_ADR 0x0 #define ROM_SP_ADR 0x0
#define POSITION1_ADR 0x1 #define ROM_SS1_ADR 0x1
#define POSITION2_ADR 0x2 #define ROM_SS2_ADR 0x2
#define ROM_EP_ADR 0x3 #define ROM_EP_ADR 0x3
//Debounce check number. //Debounce check number.
@ -46,11 +42,8 @@
#define PWM_PIN1 PB0 // Pin 5 - Motor PWM 1 #define PWM_PIN1 PB0 // Pin 5 - Motor PWM 1
#define PWM_PIN2 PB1 // Pin 6 - Motor PWM 2 #define PWM_PIN2 PB1 // Pin 6 - Motor PWM 2
#define ADC_PIN PB3 // Pin 2 - Fader position reading #define ADC_PIN PB3 // Pin 2 - Fader position reading
#define SPEED_PIN PB2 // Pin 7/ADC1
#define BUTTON_PIN PB4 // Pin 3 - Button input #define BUTTON_PIN PB4 // Pin 3 - Button input
#define MOTOR_PULSE 6 //uS motor base pulse
/*The timing of "ticks" is dependent on the AVR timer's counter register /*The timing of "ticks" is dependent on the AVR timer's counter register
* so for an 8bit register the maximum value is 256. Given we stick with * so for an 8bit register the maximum value is 256. Given we stick with
@ -89,6 +82,7 @@ typedef struct {
uint8_t timer_enabled: 1; uint8_t timer_enabled: 1;
uint8_t pressed_ticks; uint8_t pressed_ticks;
uint8_t input_pin; uint8_t input_pin;
uint8_t output_pin;
}btn_state; }btn_state;
@ -103,15 +97,9 @@ void InitProg(void);
/** /**
* @brief Reads the ADC pin from the fader. * @brief Reads the ADC pin
*/ */
uint8_t ReadFader(void); uint16_t ReadADC(void);
/**
* @brief Reads the ADC value from the Speed pot.
*/
uint8_t ReadSpeed(void);
/** /**

View File

@ -1,6 +1,4 @@
add_subdirectory(MockRegEdit)
add_subdirectory(MockADC)
add_subdirectory(TimerMock)

View File

@ -1,7 +0,0 @@
add_library(MockADC STATIC
MockADC.c
)
target_include_directories(MockADC PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)

View File

@ -1,78 +0,0 @@
/*
* Author: username
* Date: 2024
* filename: MockADC.c
* description: module_purpose
*/
#include "MockADC.h"
#include "CppUTestExt/MockSupport_c.h"
#define FAKESIZE 256
uint16_t fake_data[FAKESIZE];
int fake_index = 0;
static bool is_setup = false;
void ADC_Setup(void)
{
is_setup = true;
return;
}
void ADC_Init(uint8_t adc_chan)
{
mock_c()->actualCall("ADC_Init")
->withUnsignedIntParameters("adc_chan", adc_chan);
}
void ADC_Enable(void)
{
mock_c()->actualCall("ADC_Enable");
}
void ADC_Disable()
{
mock_c()->actualCall("ADC_Disable");
}
uint16_t ADC_ReadValue_Impl(void)
{
mock_c()->actualCall("ADC_ReadValue_Impl");
if(fake_index == 0){
return 0;
}
return fake_data[--fake_index];
}
uint16_t (*ADC_ReadValue)(void) = ADC_ReadValue_Impl;
void MockADC_PushValue(uint16_t value){
if(fake_index >= FAKESIZE - 1){
return;
}
fake_data[fake_index++] = value;
}
void MockADC_ZeroIndex(void)
{
fake_index = 0;
}
int MockADC_GetIndex(void)
{
return fake_index;
}
bool MockADC_IsSetup(void)
{
return is_setup;
}

View File

@ -1,29 +0,0 @@
/**
* @brief PUT_TEXT_HERE
* @details This file is...
* @author username
* @date todays_date
* @copyright None
* @file MOCKADC.h
*/
#ifndef MOCKADC_H
#define MOCKADC_H
#include <stdint.h>
#include <stdbool.h>
void ADC_Setup(void);
void ADC_Init(uint8_t adc_chan);
void ADC_Enable(void);
void ADC_Disable(void);
extern uint16_t (*ADC_ReadValue)(void);
void MockADC_PushValue(uint16_t value);
void MockADC_ZeroIndex(void);
int MockADC_GetIndex(void);
bool MockADC_IsSetup(void);
#endif //MOCKADC_H

View File

@ -1,12 +0,0 @@
add_library(MockRegEdit STATIC
MockRegEdit.c
)
target_include_directories(MockRegEdit PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
target_link_libraries(MockRegEdit
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
)

View File

@ -1,85 +0,0 @@
/*
* Author: username
* Date: 2024
* filename: MockRegEdit.c
* description: module_purpose
*/
#include "MockRegEdit.h"
#include "CppUTestExt/MockSupport_c.h"
void RegEdit_SetRegister(void *reg)
{
mock_c()->actualCall("RegEdit_SetRegister")
->withPointerParameters("reg", reg);
}
void RegEdit_ClearRegister(void *reg)
{
mock_c()->actualCall("RegEdit_ClearRegister")
->withPointerParameters("reg", reg);
}
void RegEdit_SetBit(void *reg, uint8_t bit_num)
{
mock_c()->actualCall("RegEdit_SetBit")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("bit_num", bit_num);
}
void RegEdit_ClearBit(void *reg, uint8_t bit_num)
{
mock_c()->actualCall("RegEdit_ClearBit")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("bit_num", bit_num);
}
bool RegEdit_IsBitSet(void *reg, uint8_t bit_num)
{
return mock_c()->actualCall("RegEdit_IsBitSet")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("bit_num", bit_num)
->returnBoolValueOrDefault(true);
//return mock_c()->returnBoolValueOrDefault(true);
}
void RegEdit_OR_Num(void *reg, uint8_t num)
{
mock_c()->actualCall("RegEdit_OR_Num")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("num", num);
}
void RegEdit_AND_Num(void *reg, uint8_t num)
{
mock_c()->actualCall("RegEdit_AND_Num")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("num", num);
}
void RegEdit_SetNum(void *reg, uint8_t num)
{
mock_c()->actualCall("RegEdit_SetNum")
->withPointerParameters("reg", reg)
->withUnsignedIntParameters("num", num);
}
uint8_t RegEdit_ReadReg(void *reg)
{
uint8_t value = *(uint8_t *)reg;
mock_c()->actualCall("RegEdit_ReadReg")
->withPointerParameters("reg", reg)
->returnUnsignedIntValueOrDefault(value);
return value;
}

View File

@ -1,30 +0,0 @@
/**
* @brief PUT_TEXT_HERE
* @details This file is...
* @author username
* @date todays_date
* @copyright None
* @file MockRegEdit.h
*/
#ifndef MOCKREGEDIT_H
#define MOCKREGEDIT_H
#include <stdint.h>
#include <stdbool.h>
void RegEdit_SetRegister(void *reg);
void RegEdit_ClearRegister(void *reg);
void RegEdit_SetBit(void *reg, uint8_t bit_num);
void RegEdit_ClearBit(void *reg, uint8_t bit_num);
bool RegEdit_IsBitSet(void *reg, uint8_t bit_num);
void RegEdit_OR_Num(void *reg, uint8_t num);
void RegEdit_AND_Num(void *reg, uint8_t num);
void RegEdit_SetNum(void *reg, uint8_t num);
uint8_t RegEdit_ReadReg(void *reg);
#endif //MOCKREGEDIT_H

View File

@ -1,51 +0,0 @@
#include "u8_comparator.hpp"
#include "CppUTest/SimpleString.h"
/*
class MyTypeComparator : public MockNamedValueComparator
{
public:
virtual bool isEqual(const void* object1, const void* object2)
{
return object1 == object2;
}
virtual SimpleString valueToString(const void* object)
{
return StringFrom(object);
}
};
*/
bool UInt8PointerComparator::isEqual(const void* object1, const void* object2) {
const uint8_t* ptr1 = reinterpret_cast<const uint8_t*>(object1);
const uint8_t* ptr2 = reinterpret_cast<const uint8_t*>(object2);
return std::memcmp(ptr1, ptr2, sizeof(uint8_t)) == 0;
}
SimpleString UInt8PointerComparator::valueToString(const void* object) {
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(object);
return StringFromFormat("0x%02x", *ptr);
}
/*
bool UInt8PointerComparator::isEqual(const void* object1, const void* object2) const {
const uint8_t* ptr1 = static_cast<const uint8_t*>(object1);
const uint8_t* ptr2 = static_cast<const uint8_t*>(object2);
return std::memcmp(ptr1, ptr2, sizeof(uint8_t)) == 0;
}
SimpleString UInt8PointerComparator::valueToString(const void* object) const {
const uint8_t* ptr = static_cast<const uint8_t*>(object);
return StringFromFormat("0x%02x", *ptr);
}
*/
bool UInt8Comparator::isEqual(const void* object1, const void* object2) {
return (uint8_t*)object1 == (uint8_t *)object2;
}
SimpleString UInt8Comparator::valueToString(const void* object) {
//uint8_t value = reinterpret_cast<uint8_t>(object);
const uint8_t *ptr = reinterpret_cast<const uint8_t*>(object);
return StringFromFormat("0x%02x", *ptr);
}

View File

@ -1,20 +0,0 @@
#ifndef U8_COMPARATOR_H
#define U8_COMPARATOR_H
#include <cstdint>
#include <cstring>
#include <CppUTestExt/MockSupport.h>
class UInt8PointerComparator : public MockNamedValueComparator {
public:
virtual bool isEqual(const void* object1, const void* object2) override;
SimpleString valueToString(const void* object) override;
};
class UInt8Comparator : public MockNamedValueComparator {
public:
virtual bool isEqual(const void* object1, const void* object2) override;
SimpleString valueToString(const void* object) override;
};
#endif //U8_COMPARATOR_H

View File

@ -1,7 +0,0 @@
add_library(TimerMock STATIC
TimerMock.c
)
target_include_directories(TimerMock PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)

View File

@ -1,31 +0,0 @@
/*
* Author: Jake G
* Date: 2024-09-02
* filename: TimerMock.c
* description: mocks timers
*/
#include "TimerMock.h"
#include <stdbool.h>
#include "CppUTestExt/MockSupport_c.h"
static bool timer_started = false;
void Timer_Start(void)
{
mock_c()->actualCall("Timer_Start");
timer_started = true;
}
void Timer_Stop(void)
{
mock_c()->actualCall("Timer_Stop");
timer_started = false;
}
uint16_t Timer_GetOverflowCount(void)
{
uint16_t time = 0xAAAA;
return mock_c()->actualCall("Timer_GetOverflowCount")
->returnUnsignedIntValueOrDefault(time);
}

View File

@ -1,26 +0,0 @@
/**
* @brief A Mock of the timer module.
* @details This file is only used for testing.
* @author Jake G
* @date 2024-09-02
* @copyright None
* @file TimerMock.h
*/
#ifndef TIMER_MOCK_H
#define TIMER_MOCK_H
#include <stdint.h>
/**
* A function
* @param a The first argument
*/
void Timer_Start(void);
void Timer_Stop(void);
uint16_t Timer_GetOverflowCount(void);
#endif //TIMER_MOCK_H

11
otto.sh
View File

@ -224,19 +224,12 @@ run_c_tests () {
make AllTests && ./tests/AllTests -c -v make AllTests && ./tests/AllTests -c -v
} }
run_mock_tests () {
format_source_code
clear_cmake_cache
cmake -DUNIT_TESTING=ON -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE} ../
make Mock_Tests && ./tests/Mock_Tests -c -v
}
print_menu () { print_menu () {
echo "BUILD MENU:" echo "BUILD MENU:"
echo "0. Add Mock Module" echo "0. Add Mock Module"
echo "1. Run Tests" echo "1. Run Tests"
echo "2. Build Project(hex)" echo "2. Build Project(hex)"
echo "3. Run MockTests" echo "3. User Option"
echo "4. Flash to AVR" echo "4. Flash to AVR"
echo "5. Add new module to project" echo "5. Add new module to project"
echo "6. Delete module from project" echo "6. Delete module from project"
@ -271,7 +264,7 @@ main() {
3) 3)
echo "You selected Option 3" echo "You selected Option 3"
valid_choice=true valid_choice=true
run_mock_tests build_hex_optimized
;; ;;
4) 4)
echo "You selected Option 4" echo "You selected Option 4"

View File

@ -1,111 +0,0 @@
/*
* Author: Jake G
* Date: 2025
* filename: ADC.c
* description: module_purpose
*/
#ifndef __AVR_ATtiny13A__
#define __AVR_ATtiny13A__
#endif
#include "ADC.h"
#include "RegEdit.h"
#include "avr/io.h"
#define MAX_CHANNEL_NUM 3
static bool IsInvalidChannel(uint8_t adc_chan) {
if (adc_chan > MAX_CHANNEL_NUM) {
return true;
}
return false;
}
uint8_t ADC_GetChannelPinNum(uint8_t adc_chan) {
switch (adc_chan) {
case 0:
return PB5;
case 1:
return PB2;
case 2:
return PB4;
case 3:
return PB3;
default:
return 255; /*return invalid pin num.*/
}
}
void ADC_Setup(void) {
// Clear the register, set VCC as ref, ADC0 as channel and
// leave result right adjusted.
RegEdit_ClearRegister((void *)&ADMUX);
// Status & Control register A
// Turn on the 8Div prescaler
RegEdit_SetNum((void *)&ADCSRA, (1 << ADPS1) | (1 << ADPS0));
// Status & Control register B
// Turn on auto-trigger using time compare/match B.
RegEdit_AND_Num((void *)&ADCSRB, (1 << ADTS2) | (0 << ADTS1) | (1 << ADTS0));
}
void ADC_Init(uint8_t adc_chan) {
if (IsInvalidChannel(adc_chan)) {
return;
}
// get the associated pin number.
uint8_t pin_num = ADC_GetChannelPinNum(adc_chan);
// set the direction to input
RegEdit_ClearBit((void *)&DDRB, pin_num);
// Disable the pull-up resistor
RegEdit_ClearBit((void *)&PORTB, pin_num);
// Set the adc mux reg for our channel.
// Clear the existing mux bits.
RegEdit_AND_Num((void *)&ADMUX, 0xFC);
// Set the correct bits
RegEdit_OR_Num((void *)&ADMUX, adc_chan);
}
void ADC_Enable(void) {
// Set the enable bit in the CTRLA register
RegEdit_SetBit((void *)&ADCSRA, ADEN);
}
void ADC_Disable() {
// Clear the enable ADC flag
RegEdit_ClearBit((void *)&ADCSRA, ADEN);
}
uint16_t ADC_ReadValue_Impl(void) {
// start conversion.
RegEdit_SetBit((void *)&ADCSRA, ADSC);
/* Wait until ADC conversion done or it times out. */
uint8_t cycles = 1;
while (1) {
if (!RegEdit_IsBitSet((void *)&ADCSRA, ADSC)) {
break;
}
// if It times out return an invalid value for a 12bit ADC.
else if (cycles >= ADC_WAIT_TIMEOUT) {
return UINT16_MAX;
}
cycles++;
}
uint16_t val = ADC;
return val;
}
// Set the default for the function pointer.
uint16_t (*ADC_ReadValue)(void) = ADC_ReadValue_Impl;

View File

@ -1,72 +0,0 @@
/**
* @brief Interface to the AVR ADC hardware.
* @details This file is...
* @author Jake G
* @date 2024
* @copyright None
* @file ADC.h
*/
#ifndef ADC_H
#define ADC_H
#include <stdbool.h>
#include <stdint.h>
/**
* @brief The number of loop cycles it waits for ADC conversion before
* timing out.
*/
#define ADC_WAIT_TIMEOUT 16
/**
* @brief Initializes the AVR hardware in order to accept
* Input for ADC usage.
* @param adc_chan The channel of the pin 0-7 you are initializing.
*
* This function only makes use of PORTA by default. It sets the direction
* register to input, disables the pull-up resistor and also diables interrupts
* alongside the input buffer(digital).
*
* This in turn helps reduce noise when using the ADC.
*
*/
void ADC_Init(uint8_t adc_chan);
/**
* @brief Returns the pin number for the adc channel or 255 on an error.
* @param The ADC channel.
*/
uint8_t ADC_GetChannelPinNum(uint8_t adc_chan);
/**
* @brief Enables the ADC
*/
void ADC_Enable(void);
/**
* @brief Disables the ADC
*/
void ADC_Disable();
/**
* @brief Reads ADC value into variable
*
*
* This function depends on the ADC already being initialized and enabled
* before being called.
*/
extern uint16_t (*ADC_ReadValue)();
/**
* @brief Sets up the ADC
*
* This function sets up the ADC to take and accumulate 32 samples. It also
* sets the inital delay to 32 ADC clock cycles, and sets the VREF to VDD or
* VCC.
*
* This function should only need to be called once.
*/
void ADC_Setup(void);
#endif // ADC_H

View File

@ -1,17 +0,0 @@
add_library(ADC STATIC
ADC.c
)
target_include_directories(ADC PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
if(UNIT_TESTING)
target_link_libraries(ADC
MockRegEdit
)
else()
target_link_libraries(ADC
RegEdit
)
endif()

View File

@ -2,12 +2,6 @@ add_executable(${PROJECT_NAME}
main.c main.c
) )
target_link_libraries(${PROJECT_NAME}
#RegEdit
#ADC
#timer
)
# Ensure the build rules are defined # Ensure the build rules are defined
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf")
@ -37,17 +31,10 @@ add_custom_target(bin ALL
endif() endif()
# Setup for default 9.6MHz
if(NOT TARGET upload) if(NOT TARGET upload)
# Upload command (adjust according to your programmer) # Upload command (adjust according to your programmer)
add_custom_target(upload ALL add_custom_target(upload ALL
COMMAND avrdude -c ${PROGRAMMER} -P ${PORT} -p ${AVR_MCU} -B 125kHz -U lfuse:w:0x6a:m -U hfuse:w:0xFF:m -U lock:w:0xFF:m -U flash:w:${CMAKE_PROJECT_NAME}.hex COMMAND avrdude -c ${PROGRAMMER} -P ${PORT} -p ${AVR_MCU} -B 125kHz -U flash:w:${CMAKE_PROJECT_NAME}.hex
DEPENDS hex DEPENDS hex
) )
endif() endif()
add_subdirectory(RegEdit)
add_subdirectory(timer)
add_subdirectory(SuperLoop)
add_subdirectory(ADC)

View File

@ -1,7 +0,0 @@
add_library(RegEdit STATIC
RegEdit.c
)
target_include_directories(RegEdit PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)

View File

@ -1,53 +0,0 @@
/*
* Author: username
* Date: 2024
* filename: RegEdit.c
* description: module_purpose
*/
#include "RegEdit.h"
void RegEdit_SetRegister(void *reg) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr = 0xFF;
}
void RegEdit_ClearRegister(void *reg) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr = 0x00;
}
void RegEdit_SetBit(void *reg, uint8_t bit_num) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr |= (uint8_t)(1 << bit_num);
}
void RegEdit_ClearBit(void *reg, uint8_t bit_num) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr &= ~(1 << bit_num);
}
bool RegEdit_IsBitSet(void *reg, uint8_t bit_num) {
uint8_t *reg_ptr = (uint8_t *)reg;
return *reg_ptr & (1 << bit_num);
}
void RegEdit_OR_Num(void *reg, uint8_t num) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr |= num;
}
void RegEdit_AND_Num(void *reg, uint8_t num) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr &= num;
}
void RegEdit_SetNum(void *reg, uint8_t num) {
uint8_t *reg_ptr = (uint8_t *)reg;
*reg_ptr = num;
}
uint8_t RegEdit_ReadReg(void *reg) {
uint8_t *reg_ptr = (uint8_t *)reg;
return *reg_ptr;
}

View File

@ -1,77 +0,0 @@
/**
* @brief Register Editing Interface
* @details This file is an abstraction to all the bitwise operations
* @author Jake G
* @date 2024
* @copyright None
* @file MockRegEdit.h
*/
#ifndef REGEDIT_H
#define REGEDIT_H
#include <stdbool.h>
#include <stdint.h>
/**
*
* @param reg The register address.
*/
void RegEdit_SetRegister(void *reg);
/**
*
* @param reg The register address.
*/
void RegEdit_ClearRegister(void *reg);
/**
*
* @param reg The register address.
* @param bit_num The bit location.
*/
void RegEdit_SetBit(void *reg, uint8_t bit_num);
/**
*
* @param reg The register address.
* @param bit_num The bit location.
*/
void RegEdit_ClearBit(void *reg, uint8_t bit_num);
/**
*
* @param reg The register address.
* @param bit_num The bit location.
* @return
*/
bool RegEdit_IsBitSet(void *reg, uint8_t bit_num);
/**
*
* @param reg The register address.
* @param num The bit location.
*/
void RegEdit_OR_Num(void *reg, uint8_t num);
/**
*
* @param reg The register address.
* @param num The bit location.
*/
void RegEdit_AND_Num(void *reg, uint8_t num);
/**
*
* @param reg The register address.
* @param num The bit location.
*/
void RegEdit_SetNum(void *reg, uint8_t num);
/**
*
* @param reg The register address.
*/
uint8_t RegEdit_ReadReg(void *reg);
#endif // REGEDIT_H

View File

@ -1,7 +0,0 @@
add_library(SuperLoop STATIC
SuperLoop.c
)
target_include_directories(SuperLoop PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)

View File

@ -1,40 +0,0 @@
/*
* Author: Jake G
* Date: 2024-09-01
* filename: SuperLoop.c
* description: The RT super loop.
*/
#include "SuperLoop.h"
#include <stdbool.h>
static uint8_t iteration_target = 0;
/*
* ####################################
* PRIVATE FUNCTIONS
* ####################################
*/
static bool continue_looping(uint8_t idx) {
if (iteration_target == 0 || idx <= iteration_target) {
return true;
}
return false;
}
/*
* ####################################
* PUBLIC FUNCTIONS
* ####################################
*/
void SuperLoop_SetIterations(uint8_t n) { iteration_target = n; }
uint8_t SuperLoop_Run(void) {
uint8_t i;
for (i = 0; continue_looping(i); i++) {
continue;
}
return i - 1;
}

View File

@ -1,29 +0,0 @@
/**
* @brief The Systems superloop that handles all the tasks.
* @details This file is the main program's logic that loops endlessly
* @author Jake G
* @date 2024-09-01
* @copyright None
* @file SUPERLOOP.h
*/
#ifndef SUPERLOOP
#define SUPERLOOP
#include <stdint.h>
/**
* A function that allows the user to set the number of loop iterations for
* testing purposes.
* @param n The number of times it will loop before breaking. (Zero is endless)
*/
void SuperLoop_SetIterations(uint8_t n);
/**
* The super loop; it runs the main code in a loop endlessly unless the number
* of iterations are set.
* @return The number of loops completed in iteration mode.
*/
uint8_t SuperLoop_Run(void);
#endif // SUPERLOOP

View File

@ -1,15 +1,14 @@
#ifndef F_CPU #ifndef F_CPU
#define F_CPU 1200000UL #define F_CPU 4800000UL
#endif #endif
#include "main.h" #include "main.h"
//#include "ADC.h"
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <util/delay.h> #include <util/delay.h>
// These are only included during development for the LSP server. // These are only included during development for the LSP server.
// #include "iotn13.h" //#include "iotn13.h"
// #include "iotn13a.h" // #include "iotn13a.h"
// ############################# // #############################
@ -33,7 +32,7 @@ volatile uint16_t tick_count;
// ############################# // #############################
static inline void InitTimer0(void); static inline void InitTimer0(void);
static void InitBtn(btn_state *b, uint8_t input_pin); static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin);
static void ClearButtonTimer(btn_state *b); static void ClearButtonTimer(btn_state *b);
static void StartButtonTimer(btn_state *b); static void StartButtonTimer(btn_state *b);
static void CheckButtonLongpress(btn_state *b); static void CheckButtonLongpress(btn_state *b);
@ -63,7 +62,7 @@ void InitProg(void) {
/*Set the debounced state to all high*/ /*Set the debounced state to all high*/
debounced_state = 0xFF; debounced_state = 0xFF;
InitBtn(&btn1, BUTTON_PIN); InitBtn(&btn1, BUTTON_PIN, PIN_ACTIVE1);
/*Wait 5ms for pull-up resistors voltage to become stable.*/ /*Wait 5ms for pull-up resistors voltage to become stable.*/
_delay_ms(5); _delay_ms(5);
@ -74,37 +73,17 @@ void InitProg(void) {
// Checks against a bit pattern we defined to represent the start of data. // Checks against a bit pattern we defined to represent the start of data.
if (eeprom_read_byte((uint8_t *)ROM_SP_ADR) == START_PATTERN) { if (eeprom_read_byte((uint8_t *)ROM_SP_ADR) == START_PATTERN) {
MotorMoveTo(eeprom_read_byte((uint8_t *)POSITION1_ADR)); MotorMoveTo(eeprom_read_byte((uint8_t *)ROM_SS1_ADR));
} else { } else {
// otherwise we write the init values for the start pattern and states. // otherwise we write the init values for the start pattern and states.
eeprom_write_byte((uint8_t *)ROM_SP_ADR, START_PATTERN); eeprom_write_byte((uint8_t *)ROM_SP_ADR, START_PATTERN);
eeprom_write_byte((uint8_t *)POSITION1_ADR, 0x7F); eeprom_write_byte((uint8_t *)ROM_SS1_ADR, 0x7F);
} }
InitTimer0(); InitTimer0();
} }
uint8_t ReadSpeed(void) { uint16_t ReadADC(void) {
// Initialize ADC
ADMUX = (0 << MUX1) | (1 << MUX0); // Select ADC1 (PB2)
ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, prescaler 8
ADCSRA |= (1 << ADSC); // Start conversion
while (ADCSRA & (1 << ADSC)) {
} // Wait for conversion to finish
//Normally a bitshift of 2 is done for 8bit ADC values,
//however we want to divide by two after this as well so we
//do a third shift followed by an addition of 127 to yield a mapping of
//approximatly 50%-96.6% duty cycle range.
uint8_t val = (uint8_t)(ADC >> 3) + 127;
return val;
}
// change to ReadFader(void)
uint8_t ReadFader(void) {
// Initialize ADC // Initialize ADC
ADMUX = (1 << MUX1) | (1 << MUX0); // Select ADC3 (PB3) ADMUX = (1 << MUX1) | (1 << MUX0); // Select ADC3 (PB3)
ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, prescaler 8 ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, prescaler 8
@ -112,7 +91,7 @@ uint8_t ReadFader(void) {
ADCSRA |= (1 << ADSC); // Start conversion ADCSRA |= (1 << ADSC); // Start conversion
while (ADCSRA & (1 << ADSC)) { while (ADCSRA & (1 << ADSC)) {
} // Wait for conversion to finish } // Wait for conversion to finish
return (uint8_t)(ADC >> 2); return ADC;
} }
/* /*
@ -128,25 +107,22 @@ static inline uint8_t diff(uint8_t a, uint8_t b) {
return b - a; return b - a;
} }
void MotorSetSavePos(uint8_t *ADR) { void MotorSetSavePos() {
uint8_t pos = ReadFader(); uint8_t pos = (uint8_t)(ReadADC() >> 2);
eeprom_write_byte((uint8_t *)ADR, pos); eeprom_write_byte((uint8_t *)ROM_SS1_ADR, pos);
return; return;
} }
uint8_t MotorGetSavedPos(uint8_t *ADR) { uint8_t MotorGetSavedPos(void) {
return (uint8_t)eeprom_read_byte((uint8_t *)ADR); return (uint8_t)eeprom_read_byte((uint8_t *)ROM_SS1_ADR);
} }
void MotorMoveTo(uint8_t target) { void MotorMoveTo(uint8_t target) {
uint8_t on_delay = ReadSpeed(); uint8_t pos = (uint8_t)(ReadADC() >> 2);
uint8_t pos = ReadFader();
uint8_t idx = 0;
while (diff(target, pos) > 4) { while (diff(target, pos) > 8) {
on_delay = ReadSpeed(); pos = (uint8_t)(ReadADC() >> 2);
pos = ReadFader();
if (target > pos) { if (target > pos) {
MotorMove(1); MotorMove(1);
} else { } else {
@ -154,20 +130,15 @@ void MotorMoveTo(uint8_t target) {
} }
// The delay ratio controlls the PWM waveforms. // The delay ratio controlls the PWM waveforms.
for (idx = 0; idx < on_delay; idx++) { //_delay_ms(5);
_delay_us(MOTOR_PULSE); // MotorCoast();
} // _delay_ms(5);
MotorCoast();
for (; idx < 255; idx++) {
_delay_us(MOTOR_PULSE);
}
} }
return; return;
} }
// Using the compatable bool type. // Using the compatable bool type.
// The motor being used seems to stop working below a 50% duty cycle.
void MotorMove(uint8_t fwd) { void MotorMove(uint8_t fwd) {
if (fwd) { if (fwd) {
PORTB |= (1 << PWM_PIN1); PORTB |= (1 << PWM_PIN1);
@ -190,17 +161,21 @@ void MotorCoast(void) {
*/ */
/*This is kinda like our button constructor*/ /*This is kinda like our button constructor*/
static void InitBtn(btn_state *b, uint8_t input_pin) { static void InitBtn(btn_state *b, uint8_t input_pin, uint8_t output_pin) {
b->is_long_pressed = 0; b->is_long_pressed = 0;
b->is_pressed = 0; b->is_pressed = 0;
b->is_active = 0; b->is_active = 0;
b->pressed_ticks = 0; b->pressed_ticks = 0;
b->timer_enabled = 0; b->timer_enabled = 0;
b->input_pin = input_pin; b->input_pin = input_pin;
b->output_pin = output_pin;
/*Configure the buttons inputs and outputs*/ /*Configure the buttons inputs and outputs*/
DDRB &= ~(1 << b->input_pin); DDRB &= ~(1 << b->input_pin);
PORTB |= (1 << b->input_pin); PORTB |= (1 << b->input_pin);
DDRB |= (1 << b->output_pin);
PORTB &= ~(1 << b->output_pin);
} }
static void ClearButtonTimer(btn_state *b) { static void ClearButtonTimer(btn_state *b) {
@ -244,7 +219,6 @@ static void UpdateButtonOutput(btn_state *b) {
/*Then start the timer and update the output*/ /*Then start the timer and update the output*/
// ToggleOutput(b); // ToggleOutput(b);
StartButtonTimer(b); StartButtonTimer(b);
return; return;
} }
@ -264,21 +238,12 @@ static void UpdateButtonOutput(btn_state *b) {
else if (!b->is_pressed) { else if (!b->is_pressed) {
/*If the button was released on a long press.*/ /*If the button was released on a long press.*/
if (b->is_long_pressed) { if (b->is_long_pressed) {
MotorSetSavePos((uint8_t *)POSITION1_ADR); MotorSetSavePos();
} }
/*If the button pres was a short one.*/ /*If the button pres was a short one.*/
else if (!b->is_long_pressed) { else if (!b->is_long_pressed) {
if (b->is_active) { if (b->is_active) {
MotorMoveTo(MotorGetSavedPos());
/*If already in saved position then go back to original pos.*/
if(diff(MotorGetSavedPos((uint8_t *)POSITION1_ADR), ReadFader()) < 4){
MotorMoveTo(MotorGetSavedPos((uint8_t *)POSITION2_ADR));
}
else{
/*Save the current position into position 2 EEPROM*/
MotorSetSavePos((uint8_t *)POSITION2_ADR);
MotorMoveTo(MotorGetSavedPos((uint8_t *)POSITION1_ADR));
}
} else { } else {
MotorCoast(); MotorCoast();
} }

View File

@ -1,17 +0,0 @@
add_library(timer STATIC
timer.c
)
target_include_directories(timer PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
if(UNIT_TESTING)
target_link_libraries(timer
MockRegEdit
)
else()
target_link_libraries(timer
RegEdit
)
endif()

View File

@ -1,75 +0,0 @@
/**
* @brief PUT_TEXT_HERE
* @details This file is...
* @author username
* @date todays_date
* @copyright None
* @file module_name.h
*/
// Used during testing and for the LSP
#ifndef __AVR_ATtiny404__
#define __AVR_ATtiny404__
#endif
#include "timer.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#define FCLK_PER 3333333UL
#define DIV8 0x3
#define PERIOD_VALUE 40
// These are expiremential found values that account for overhead
// for smaller durations.
#define OVERHEAD_ONE 226
#define OVERHEAD_TWO 151
#define OVERHEAD_THREE 75
static uint16_t overflow_count = 0;
uint16_t Timer_GetOverflowCount(void) { return overflow_count; }
void Timer_Start(void) {
// clear the overflow event count
overflow_count = 0;
sei();
// Enable the overflow Interrupt.
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
// set Normal mode.
TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;
// Disable event counting.
TCA0.SINGLE.EVCTRL &= ~(TCA_SINGLE_CNTEI_bm);
// Set the Period Value
TCA0.SINGLE.PER = PERIOD_VALUE;
// set the Timer to divide FCLK_PER by 8.
TCA0.SINGLE.CTRLA |= (DIV8 << 1);
// Enable the Timer
TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;
}
void Timer_Disable(void) {
cli();
TCA0.SINGLE.CTRLA &= ~(1 << 0);
TCA0.SINGLE.CTRLESET |= ((0x3) << 2);
}
// Triggered on the overflow of the timer A's counter.
ISR(TCA0_OVF_vect) {
cli();
// Increment the Overflow counter.
overflow_count += 1;
// The interrupt flag has to be cleared manually
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
sei();
}

View File

@ -1,32 +0,0 @@
/**
* @brief The AVR Timer module
* @details This file is used to interact with the hardware timers.
* @author Jake G
* @date 2024
* @copyright None
* @file TIMER.h
*/
#ifndef TIMER
#define TIMER
#include "inttypes.h"
#include "stdbool.h"
/**
* Starts up the AVR timer using a 10KHz frequency
*/
void Timer_Start(void);
/**
* Stops the AVR timer.
*/
void Timer_Stop(void);
/**
* Get the number of times the timer's counter setup for 10kHz overflowed.
* @return A uint16_t holding the number of counter overflow events.
*/
uint16_t Timer_GetOverflowCount(void);
#endif // TIMER

View File

@ -1,18 +0,0 @@
# TEST_RUNNER
add_library(test_ADC
test_ADC.cpp
)
target_link_libraries(test_ADC
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
ADC
MockRegEdit
)
#Needed for the tests to function
include_directories(
/usr/local/avr/include/avr
#/usr/local/avr/avr/include #for Linux
#/usr/lib/avr/include/avr
)

View File

@ -1,188 +0,0 @@
/*
* Author: Jake G
* Date: 2025
* filename: test_ADC.c
* description: module_purpose
*/
#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTestExt/MockSupport.h"
#include <cstdint>
//This define allows us to dircetly include the device header without error.
#define _AVR_IO_H_
extern "C"
{
#include "sfr_defs.h"
#include <iotn13a.h> //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 return the "error" value
uint16_t value = ADC_ReadValue();
CHECK_EQUAL_TEXT(UINT16_MAX, value, "ERROR: Should return UINT16_MAX!");
}
static uint16_t ADC_ReadValueFake()
{
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();
LONGS_EQUAL(512, value);
}

View File

@ -3,10 +3,6 @@
//ImportTestGroups //ImportTestGroups
IMPORT_TEST_GROUP(simple_test); IMPORT_TEST_GROUP(simple_test);
IMPORT_TEST_GROUP(test_SuperLoop);
IMPORT_TEST_GROUP(test_ADC);
IMPORT_TEST_GROUP(test_RegEdit);
//START: main //START: main
int main(int argc, char** argv) int main(int argc, char** argv)

View File

@ -1,13 +1,7 @@
project(Tests) project(Tests)
# TEST_DIRS # TEST_DIRS
add_subdirectory(SuperLoop)
add_subdirectory(ADC)
add_subdirectory(MockADC)
add_subdirectory(RegEdit)
add_subdirectory(MockRegEdit)
add_subdirectory(simple_test) add_subdirectory(simple_test)
#add_subdirectory(timer)
# TEST_RUNNER # TEST_RUNNER
add_executable(AllTests add_executable(AllTests
@ -18,19 +12,5 @@ target_link_libraries(AllTests
${CPPUTEST_LIBRARIES}/libCppUTest.a ${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a ${CPPUTEST_LIBRARIES}/libCppUTestExt.a
# TEST_LINKS # TEST_LINKS
test_SuperLoop
test_ADC
test_RegEdit
simple_test simple_test
) )
add_executable(Mock_Tests
MockTests.cpp
)
target_link_libraries(Mock_Tests
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
test_MockRegEdit
test_MockADC
)

View File

@ -1,10 +0,0 @@
# TEST_RUNNER
add_library(test_MockADC
test_MockADC.cpp
)
target_link_libraries(test_MockADC
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
MockADC
)

View File

@ -1,92 +0,0 @@
/*
* Author: Jake G
* Date: 2024
* filename: test_MockADC.c
* description:
*/
#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTestExt/MockSupport.h"
#include <cstdint>
extern "C"
{
#include "MockADC.h"
}
TEST_GROUP(test_MockADC)
{
void setup()
{
}
void teardown()
{
mock().checkExpectations();
mock().clear();
}
};
TEST(test_MockADC, ADC_InitExpects)
{
mock().expectOneCall("ADC_Init")
.withUnsignedIntParameter("adc_chan", 0);
ADC_Init(0);
}
TEST(test_MockADC, ADC_EnableExpects)
{
mock().expectOneCall("ADC_Enable");
ADC_Enable();
}
TEST(test_MockADC, ADC_DisableExpect)
{
mock().expectOneCall("ADC_Disable");
ADC_Disable();
}
TEST(test_MockADC, ADC_ReadValue)
{
MockADC_ZeroIndex();
MockADC_PushValue(512);
mock().expectOneCall("ADC_ReadValue_Impl");
uint16_t val = ADC_ReadValue();
LONGS_EQUAL(512, val);
}
TEST(test_MockADC, ADC_ReadValueReturnsZeroOnEmptyBuffer)
{
MockADC_ZeroIndex();
mock().expectOneCall("ADC_ReadValue_Impl")
.andReturnValue(0x0000);
uint16_t val = ADC_ReadValue();
LONGS_EQUAL(0, val);
}
TEST(test_MockADC, MockADC_PushValueDoesntOverflowArray)
{
MockADC_ZeroIndex();
for(int i = 0; i < 257; i++){
MockADC_PushValue(512+i);
CHECK_TRUE(MockADC_GetIndex() <= 255);
}
}
TEST(test_MockADC, MockADC_SetupSetsGlobal)
{
CHECK_FALSE(MockADC_IsSetup());
ADC_Setup();
CHECK_TRUE(MockADC_IsSetup());
}

View File

@ -1,11 +0,0 @@
# TEST_RUNNER
add_library(test_MockRegEdit
test_MockRegEdit.cpp
)
target_link_libraries(test_MockRegEdit
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
MockRegEdit
)

View File

@ -1,168 +0,0 @@
/*
* Author: username
* Date: todays_date
* filename: test_MockRegEdit.c
* description: module_purpose
*/
#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTestExt/MockSupport.h"
#include <cstdint>
extern "C"
{
#include "MockRegEdit.h"
}
TEST_GROUP(test_MockRegEdit)
{
void setup()
{
}
void teardown()
{
mock().clear();
}
};
TEST(test_MockRegEdit, RegEdit_ClearRegisterExpectedCallPasses)
{
uint8_t a;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_ClearRegister")
.withPointerParameter("reg", b);
RegEdit_ClearRegister(b);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_SetRegisterExpectedCallPasses)
{
uint8_t a;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_SetRegister")
.withPointerParameter("reg", b);
RegEdit_SetRegister(b);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_SetBitExpectedCallPasses)
{
uint8_t a;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_SetBit")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("bit_num", 5);
RegEdit_SetBit(b, 5);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_ClearBitExpectedCallPasses)
{
uint8_t a;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_ClearBit")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("bit_num", 5);
RegEdit_ClearBit(b, 5);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_IsBitSetExpectedCallPasses)
{
uint8_t a = 0xFF;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_IsBitSet")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("bit_num", 5)
.andReturnValue(true);
CHECK_TRUE(RegEdit_IsBitSet(b, 5));
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_IsBitSetExpectedCallPassesWithFalse)
{
uint8_t a = 0xFF;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_IsBitSet")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("bit_num", 5)
.andReturnValue(false);
CHECK_FALSE(RegEdit_IsBitSet(b, 5));
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_OR_NumExpectedWorks)
{
uint8_t a = 0xFF;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_OR_Num")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("num", 0x4)
.andReturnValue(false);
RegEdit_OR_Num(b, 0x4);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_SetNumPasses)
{
uint8_t a = 0xFF;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_SetNum")
.withPointerParameter("reg", b)
.withUnsignedIntParameter("num", 0x4)
.andReturnValue(false);
RegEdit_SetNum(b, 0x4);
mock().checkExpectations();
}
TEST(test_MockRegEdit, RegEdit_ReadRegPasses)
{
uint8_t a = 0xFF;
uint8_t *b = &a;
mock().expectOneCall("RegEdit_ReadReg")
.withPointerParameter("reg", b)
.andReturnValue(0xFF);
uint8_t reg_val = RegEdit_ReadReg(b);
LONGS_EQUAL(0xFF, reg_val);
mock().checkExpectations();
}

View File

@ -1,13 +0,0 @@
#include "CppUTest/CommandLineTestRunner.h"
//ImportTestGroups
IMPORT_TEST_GROUP(test_MockRegEdit);
IMPORT_TEST_GROUP(test_MockADC);
//START: main
int main(int argc, char** argv)
{
return RUN_ALL_TESTS(argc, argv);
}
//END: main

View File

@ -1,10 +0,0 @@
# TEST_RUNNER
add_library(test_RegEdit
test_RegEdit.cpp
)
target_link_libraries(test_RegEdit
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
RegEdit
)

View File

@ -1,32 +0,0 @@
/*
* Author: username
* Date: todays_date
* filename: test_RegEdit.c
* description: module_purpose
*/
#include "CppUTest/CommandLineTestRunner.h"
extern "C"
{
#include "RegEdit.h"
}
TEST_GROUP(test_RegEdit)
{
void setup()
{
}
void teardown()
{
}
};
TEST(test_RegEdit, FirstTest)
{
//FAIL("Fail me!");
CHECK(true);
}

View File

@ -1,10 +0,0 @@
# TEST_RUNNER
add_library(test_SuperLoop
test_SuperLoop.cpp
)
target_link_libraries(test_SuperLoop
${CPPUTEST_LIBRARIES}/libCppUTest.a
${CPPUTEST_LIBRARIES}/libCppUTestExt.a
SuperLoop
)

View File

@ -1,36 +0,0 @@
/*
* Author: Jake G
* Date: 2024-09-01
* filename: test_SuperLoop.c
* description: module_purpose
*/
#include "CppUTest/CommandLineTestRunner.h"
extern "C"
{
#include "SuperLoop.h"
}
TEST_GROUP(test_SuperLoop)
{
void setup()
{
}
void teardown()
{
}
};
TEST(test_SuperLoop, LoopIterationsFiniteWork){
for(uint8_t i = 1; i < 255; i++){
SuperLoop_SetIterations(i);
uint8_t num_iterations = SuperLoop_Run();
CHECK_EQUAL(i, num_iterations);
}
}