Added needed modules from the HIGH repo

This commit is contained in:
jakeg00dwin 2024-09-02 13:52:30 -07:00
parent 97e4664adb
commit 2a3ea0280a
10 changed files with 451 additions and 0 deletions

112
src/ADC/ADC.c Normal file
View File

@ -0,0 +1,112 @@
/*
* 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;

74
src/ADC/ADC.h Normal file
View File

@ -0,0 +1,74 @@
/**
* @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 <stdint.h>
#include <stdbool.h>
/**
* @brief Initializes the AVR hardware in order to accept
* Input for ADC usage.
* @param pin_num The number 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 pin_num);
/**
* @brief Enables the ADC
*/
void ADC_Enable(void);
/**
* @brief Disables the ADC
*/
void ADC_Disable();
/**
* @brief Reads ADC value into variable
*
* @param pin_num The bin number of the ADC pin being read.
*
* This function depends on the ADC already being initialized and enabled
* before being called.
*/
extern uint16_t (*ADC_ReadValue)(uint8_t pin_num);
/**
* @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);
/**
* @brief Sets the pin used in the MUX for ADC0.
*
* @param pin_num The number of the pin in Port A.
*/
void ADC_SetPin(uint8_t pin_num);
#endif //ADC_H

17
src/ADC/CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
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

@ -57,3 +57,6 @@ add_subdirectory(timer)
add_subdirectory(SuperLoop)
add_subdirectory(Relays)
add_subdirectory(zero_cross_detection)
add_subdirectory(ADC)
add_subdirectory(load)

18
src/load/CMakeLists.txt Normal file
View File

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

75
src/load/load.c Normal file
View File

@ -0,0 +1,75 @@
/*
* Author: Jake G
* Date: 2024
* filename: load.c
* description: module_purpose
*/
#ifndef __AVR_ATtiny404__
#define __AVR_ATtiny404__
#endif
#include <avr/io.h>
#include "load.h"
#ifndef UNIT_TESTING
#include "ADC.h"
#include "RegEdit.h"
#else
#include "MockADC/MockADC.h"
#include "MockRegEdit.h"
#endif
//These two arrays allow us to track the A and B ports to know when
//one has been disabled before.
static bool porta_disabled[8] = {0};
static bool portb_disabled[8] = {0};
static bool valid_load(uint16_t val)
{
if(val > 527 && val < 1000) {
return true;
}
return false;
}
void Load_HandleLoadPortA(uint8_t adc_pin, uint8_t out_pin)
{
ADC_Init(adc_pin);
ADC_Enable();
ADC_SetPin(adc_pin);
uint16_t val = ADC_ReadValue(adc_pin);
ADC_Disable();
if(valid_load(val) && !porta_disabled[adc_pin]){
RegEdit_SetBit((void *) &PORTA.DIR, out_pin);
RegEdit_SetBit((void *) &PORTA.OUT, out_pin);
}
else{
RegEdit_ClearBit((void *) &PORTA.OUT, out_pin);
porta_disabled[adc_pin] = true;
}
}
void Load_HandleLoadPortB(uint8_t adc_pin, uint8_t out_pin)
{
ADC_Init(adc_pin);
ADC_Enable();
ADC_SetPin(adc_pin);
uint16_t val = ADC_ReadValue(adc_pin);
ADC_Disable();
if(valid_load(val) && !portb_disabled[adc_pin]){
RegEdit_SetBit((void *) &PORTB.DIR, out_pin);
RegEdit_SetBit((void *) &PORTB.OUT, out_pin);
}
else{
RegEdit_ClearBit((void *) &PORTB.OUT, out_pin);
portb_disabled[adc_pin] = true;
}
}

32
src/load/load.h Normal file
View File

@ -0,0 +1,32 @@
/**
* @brief Module for handling the ADC input from the load pins.
* @details This file holds the functions for reading the ADC values.
* @author Jake G
* @date 2024
* @copyright None
* @file load.h
*/
#ifndef LOAD_H
#define LOAD_H
/**
* @brief Low Threshold
*
*/
#define LOWTHRESH 527
/**
* @brief High Threshold
*
*/
#define HIGHTHRESH 1000
void Load_HandleLoadPortA(uint8_t adc_pin, uint8_t out_pin);
void Load_HandleLoadPortB(uint8_t adc_pin, uint8_t out_pin);
void Load_HandlePinLoads(void);
#endif /* LOAD_H */

View File

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

View File

@ -0,0 +1,54 @@
/*
* Author: Jake G
* Date: 2024
* filename: zero_cross_detection.c
* description:
*/
#include "zero_cross_detection.h"
#define TRIGGERVAL 512
#ifndef UNIT_TESTING
#include "ADC.h"
#else
#include "MockADC/MockADC.h"
#endif
#define ZCD_PIN 0x07
void ZCD_Setup(void)
{
ADC_Init(ZCD_PIN);
ADC_SetPin(ZCD_PIN);
ADC_Enable();
}
bool ZCD_IsTriggered()
{
uint16_t first, second;
ZCD_Setup();
first = ADC_ReadValue(ZCD_PIN);
ADC_Disable();
ZCD_Setup();
second = ADC_ReadValue(ZCD_PIN);
ADC_Disable();
if(second < TRIGGERVAL){
return false;
}
if(second < first){
return false;
}
return true;
}
void ZCD_Poll(void)
{
while(true){
if(ZCD_IsTriggered()){
break;
}
}
}

View File

@ -0,0 +1,49 @@
/**
* @file zero_cross_detection.h
* @author Jake G
* @date 16 June 2024
* @brief File contains the zero cross detection functions
*
* This file holds all the code/functions needed to read the value of the AC
* waveform. It uses the trigger value from the `config.h` file to evaluate the
* state.
*
* This module depends on the ADC.h module to get readings from the ADC
* hardware.
*/
#ifndef ZERO_CROSS_DETECTION
#define ZERO_CROSS_DETECTION
#include <stdint.h>
#include <stdbool.h>
/**
* @brief Zero Cross Detection Setup
*
* Sets up the hardware to read the values coming from the AC input waveform.
*
*/
void ZCD_Setup(void);
//int ZCD_Setup(volatile uint8_t *ddrx, uint8_t *port, uint8_t pin);
/**
* @brief Checks if ZCD should trigger on value
*
* The function checks for a positive edge first using the ZCD_IsPositiveEdge
* function. If a positive edge was found, then it takes an addition set of
* samples and averages them; only triggering(returning true) in the case
* that the average is higher than the previous sample.
*/
bool ZCD_IsTriggered(void);
/**
* @brief Function blocks execution until ZCD is triggered.
*
*/
void ZCD_Poll(void);
#endif //ZERO_CROSS_DETECTION