Refactored timer for F0
This commit is contained in:
117
CMakeLists.txt
117
CMakeLists.txt
@@ -3,15 +3,15 @@ cmake_minimum_required(VERSION 3.19)
|
|||||||
project(shmingo-HAL)
|
project(shmingo-HAL)
|
||||||
set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
set(MCU_FAMILY "STM32L4xx" CACHE STRING "MCU family")
|
set(MCU_FAMILY "STM32F0xx")
|
||||||
set(MCU_MODEL "STM32L432xx" CACHE STRING "MCU model")
|
set(MCU_MODEL "STM32F072xB")
|
||||||
|
|
||||||
set(CPU_PARAMETERS
|
set(CPU_PARAMETERS
|
||||||
-mcpu=cortex-m4
|
-mcpu=cortex-m0
|
||||||
-mthumb)
|
-mthumb)
|
||||||
|
|
||||||
set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/L432KC/startup_stm32l432kcux.s)
|
set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/F072RB/startup_stm32f072rbtx.s)
|
||||||
set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/L432KC/STM32L432KCUX_FLASH.ld)
|
set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/F072RB/STM32F072RBTX_FLASH.ld)
|
||||||
|
|
||||||
set(EXECUTABLE ${CMAKE_PROJECT_NAME})
|
set(EXECUTABLE ${CMAKE_PROJECT_NAME})
|
||||||
enable_language(C CXX ASM)
|
enable_language(C CXX ASM)
|
||||||
@@ -23,87 +23,94 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
set(CMAKE_CXX_EXTENSIONS ON)
|
set(CMAKE_CXX_EXTENSIONS ON)
|
||||||
|
|
||||||
set(MX_INCLUDE_DIRECTORIES
|
set(MX_INCLUDE_DIRECTORIES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include
|
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include
|
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PROJECT_INCLUDE_DIRECTORIES
|
set(PROJECT_INCLUDE_DIRECTORIES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
|
||||||
|
#[[
|
||||||
|
SHAL/Include/Peripheral/UART
|
||||||
|
SHAL/Include/Peripheral/UART/Reg
|
||||||
|
SHAL/Include/Peripheral/I2C
|
||||||
|
SHAL/Include/Peripheral/I2C/Reg
|
||||||
|
SHAL/Include/Peripheral/ADC
|
||||||
|
SHAL/Include/Peripheral/ADC/Reg
|
||||||
|
SHAL/Include/Peripheral/EXT
|
||||||
|
SHAL/Include/Peripheral/EXT/Reg
|
||||||
|
]]#
|
||||||
SHAL/Include/Core/
|
SHAL/Include/Core/
|
||||||
SHAL/Include/Peripheral/Timer
|
|
||||||
SHAL/Include/Peripheral/Timer/Reg
|
|
||||||
SHAL/Include/Peripheral/GPIO
|
SHAL/Include/Peripheral/GPIO
|
||||||
SHAL/Include/Peripheral/GPIO/Reg
|
SHAL/Include/Peripheral/GPIO/Reg
|
||||||
SHAL/Include/Peripheral/UART
|
SHAL/Include/Peripheral/Timer
|
||||||
SHAL/Include/Peripheral/UART/Reg
|
SHAL/Include/Peripheral/Timer/Reg
|
||||||
SHAL/Include/Peripheral/I2C
|
|
||||||
SHAL/Include/Peripheral/I2C/Reg
|
|
||||||
SHAL/Include/Peripheral/ADC
|
|
||||||
SHAL/Include/Peripheral/ADC/Reg
|
|
||||||
SHAL/Include/Peripheral/EXT/
|
|
||||||
SHAL/Include/Peripheral/EXT/Reg
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE PROJECT_SOURCES
|
file(GLOB_RECURSE PROJECT_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.c
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.c
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.c
|
||||||
|
#${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/main.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/main.cpp
|
||||||
|
|
||||||
|
#Temporary manual method of including source files to avoid including broken code
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/GPIO/*.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/Timer/*.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Core/*.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(${EXECUTABLE}
|
add_executable(${EXECUTABLE}
|
||||||
${PROJECT_SOURCES}
|
${PROJECT_SOURCES}
|
||||||
${STARTUP_SCRIPT}
|
${STARTUP_SCRIPT}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(${EXECUTABLE} PRIVATE
|
target_compile_definitions(${EXECUTABLE} PRIVATE
|
||||||
${MCU_MODEL}
|
${MCU_MODEL}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${EXECUTABLE} PRIVATE
|
target_include_directories(${EXECUTABLE} PRIVATE
|
||||||
${MX_INCLUDE_DIRECTORIES}
|
${MX_INCLUDE_DIRECTORIES}
|
||||||
${PROJECT_INCLUDE_DIRECTORIES}
|
${PROJECT_INCLUDE_DIRECTORIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(${EXECUTABLE} PRIVATE
|
target_compile_options(${EXECUTABLE} PRIVATE
|
||||||
${CPU_PARAMETERS}
|
${CPU_PARAMETERS}
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
-Wpedantic
|
-Wpedantic
|
||||||
-Wno-unused-parameter
|
-Wno-unused-parameter
|
||||||
-Wno-switch
|
$<$<COMPILE_LANGUAGE:CXX>:
|
||||||
-Wno-implicit-fallthrough
|
-Wno-volatile
|
||||||
$<$<COMPILE_LANGUAGE:CXX>:
|
-Wsuggest-override>
|
||||||
-Wno-volatile
|
|
||||||
-Wsuggest-override>
|
$<$<CONFIG:Debug>:-Og -g3 -ggdb>
|
||||||
|
$<$<CONFIG:Release>:-Og -g0>
|
||||||
$<$<CONFIG:Debug>:-Og -g3 -ggdb>
|
|
||||||
$<$<CONFIG:Release>:-Og -g0>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_options(${EXECUTABLE} PRIVATE
|
target_link_options(${EXECUTABLE} PRIVATE
|
||||||
-T${MCU_LINKER_SCRIPT}
|
-T${MCU_LINKER_SCRIPT}
|
||||||
${CPU_PARAMETERS}
|
${CPU_PARAMETERS}
|
||||||
-Wl,-Map=${CMAKE_PROJECT_NAME}.map
|
-Wl,-Map=${CMAKE_PROJECT_NAME}.map
|
||||||
--specs=nosys.specs
|
--specs=nosys.specs
|
||||||
-Wl,--start-group
|
-Wl,--start-group
|
||||||
-lc
|
-lc
|
||||||
-lm
|
-lm
|
||||||
-lstdc++
|
-lstdc++
|
||||||
-lsupc++
|
-lsupc++
|
||||||
-Wl,--end-group
|
-Wl,--end-group
|
||||||
-Wl,--print-memory-usage
|
-Wl,--print-memory-usage
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
|
||||||
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${EXECUTABLE}>
|
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${EXECUTABLE}>
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
|
||||||
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${EXECUTABLE}>
|
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${EXECUTABLE}>
|
||||||
${EXECUTABLE}.hex
|
${EXECUTABLE}.hex
|
||||||
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}>
|
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}>
|
||||||
${EXECUTABLE}.bin
|
${EXECUTABLE}.bin
|
||||||
)
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file startup_stm32f072xb.s
|
* @file startup_stm32f072xb.s
|
||||||
* @author MCD Application Team
|
* @author MCD Application Team
|
||||||
|
|||||||
11
Makefile
11
Makefile
@@ -5,12 +5,9 @@ BUILD_DIR := build
|
|||||||
BUILD_TYPE ?= Debug
|
BUILD_TYPE ?= Debug
|
||||||
TOOLCHAIN := gcc-arm-none-eabi.cmake
|
TOOLCHAIN := gcc-arm-none-eabi.cmake
|
||||||
|
|
||||||
CFLAGS_DEBUG ?= -g3 -O0
|
|
||||||
CXXFLAGS_DEBUG ?= -g3 -O0
|
|
||||||
|
|
||||||
# MCU target (override on command line: make build MCU_MODEL=STM32F051x8)
|
# MCU target (override on command line: make build MCU_MODEL=STM32F051x8)
|
||||||
MCU_MODEL ?= STM32L432xx
|
MCU_MODEL ?= STM32F072xB
|
||||||
MCU_FAMILY ?= STM32L4xx
|
MCU_FAMILY ?= STM32F0xx
|
||||||
|
|
||||||
# --- Default target ---
|
# --- Default target ---
|
||||||
all: build
|
all: build
|
||||||
@@ -23,8 +20,6 @@ ${BUILD_DIR}/build.ninja:
|
|||||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} \
|
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} \
|
||||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||||
-DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" \
|
|
||||||
-DCMAKE_CXX_FLAGS_DEBUG="${CXXFLAGS_DEBUG}" \
|
|
||||||
-DMCU_MODEL=$(MCU_MODEL) \
|
-DMCU_MODEL=$(MCU_MODEL) \
|
||||||
-DMCU_FAMILY=$(MCU_FAMILY)
|
-DMCU_FAMILY=$(MCU_FAMILY)
|
||||||
|
|
||||||
@@ -43,4 +38,4 @@ format: $(addsuffix .format,${SRCS})
|
|||||||
|
|
||||||
# --- Clean ---
|
# --- Clean ---
|
||||||
clean:
|
clean:
|
||||||
rm -rf ${BUILD_DIR} compile_commands.json
|
rm -rf ${BUILD_DIR} compile_commands.json
|
||||||
10
README.md
10
README.md
@@ -1,3 +1,9 @@
|
|||||||
# Shmingo-HAL
|
Instructions to run
|
||||||
|
|
||||||
A custom HAL for STM32F0 MCUs
|
A binary is provided (Shmingo-HAL, formats are bin,hex,elf)
|
||||||
|
|
||||||
|
Download STM32CubeProgrammer
|
||||||
|
point to the binary file
|
||||||
|
Program via SWD (on Nucleo devices, you can just plug into USB and connect via onboard USB to SWD adapter)
|
||||||
|
|
||||||
|
You can also use an external ST-Link to program with the dedicated SWD pins
|
||||||
@@ -8,6 +8,30 @@
|
|||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
#include "SHAL_ADC_TYPES.h"
|
#include "SHAL_ADC_TYPES.h"
|
||||||
|
|
||||||
|
enum class SHAL_ADC_Channel : uint32_t { //TODO remove unused or non existing channels?
|
||||||
|
CH0 = 0,
|
||||||
|
CH1,
|
||||||
|
CH2,
|
||||||
|
CH3,
|
||||||
|
CH4,
|
||||||
|
CH5,
|
||||||
|
CH6,
|
||||||
|
CH7,
|
||||||
|
CH8,
|
||||||
|
CH9,
|
||||||
|
CH10,
|
||||||
|
CH11,
|
||||||
|
CH12,
|
||||||
|
CH13,
|
||||||
|
CH14,
|
||||||
|
CH15,
|
||||||
|
CH16,
|
||||||
|
CHTemp,
|
||||||
|
CHRef,
|
||||||
|
CHBat,
|
||||||
|
NO_ADC_MAPPING
|
||||||
|
};
|
||||||
|
|
||||||
#define SHAL_ADC1 SHAL_ADC(1)
|
#define SHAL_ADC1 SHAL_ADC(1)
|
||||||
|
|
||||||
enum class ADC_Key : uint8_t{
|
enum class ADC_Key : uint8_t{
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static volatile ADC_TypeDef* ADC_TABLE[1] = { //Lookup table for ADCs
|
|||||||
};
|
};
|
||||||
|
|
||||||
static inline SHAL_ADC_Common_Control_Reg getADCCommonControl() {
|
static inline SHAL_ADC_Common_Control_Reg getADCCommonControl() {
|
||||||
return {&ADC1_COMMON->CCR ,ADC_CCR_VREFEN,ADC_CCR_TSEN,ADC_CCR_VBATEN};
|
return {&ADC1_COMMON->CCR,ADC_CCR_VREFEN,ADC_CCR_TSEN,ADC_CCR_VBATEN};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(ADC_Key key){
|
static inline SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(ADC_Key key){
|
||||||
|
|||||||
@@ -29,66 +29,29 @@ enum class GPIO_Key : uint8_t {
|
|||||||
INVALID
|
INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static volatile GPIO_TypeDef * GPIO_TABLE[3] = { //Lookup table for ADCs
|
||||||
|
GPIOA,
|
||||||
|
GPIOB,
|
||||||
|
GPIOC,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t getGPIOPinNumber(GPIO_Key key){
|
||||||
constexpr SHAL_GPIO_Peripheral getGPIORegister(const GPIO_Key g){
|
return static_cast<uint8_t>(key) % 16;
|
||||||
switch(g) {
|
|
||||||
case GPIO_Key::A0: return {GPIOA,0};
|
|
||||||
case GPIO_Key::A1: return {GPIOA,1};
|
|
||||||
case GPIO_Key::A2: return {GPIOA,2};
|
|
||||||
case GPIO_Key::A3: return {GPIOA,3};
|
|
||||||
case GPIO_Key::A4: return {GPIOA,4};
|
|
||||||
case GPIO_Key::A5: return {GPIOA,5};
|
|
||||||
case GPIO_Key::A6: return {GPIOA,6};
|
|
||||||
case GPIO_Key::A7: return {GPIOA,7};
|
|
||||||
case GPIO_Key::A8: return {GPIOA,8};
|
|
||||||
case GPIO_Key::A9: return {GPIOA,9};
|
|
||||||
case GPIO_Key::A10: return {GPIOA,10};
|
|
||||||
case GPIO_Key::A11: return {GPIOA,11};
|
|
||||||
case GPIO_Key::A12: return {GPIOA,12};
|
|
||||||
case GPIO_Key::A13: return {GPIOA,13};
|
|
||||||
case GPIO_Key::A14: return {GPIOA,14};
|
|
||||||
case GPIO_Key::A15: return {GPIOA,15};
|
|
||||||
case GPIO_Key::B0: return {GPIOB,0};
|
|
||||||
case GPIO_Key::B1: return {GPIOB,1};
|
|
||||||
case GPIO_Key::B2: return {GPIOB,2};
|
|
||||||
case GPIO_Key::B3: return {GPIOB,3};
|
|
||||||
case GPIO_Key::B4: return {GPIOB,4};
|
|
||||||
case GPIO_Key::B5: return {GPIOB,5};
|
|
||||||
case GPIO_Key::B6: return {GPIOB,6};
|
|
||||||
case GPIO_Key::B7: return {GPIOB,7};
|
|
||||||
case GPIO_Key::B8: return {GPIOB,8};
|
|
||||||
case GPIO_Key::B9: return {GPIOB,9};
|
|
||||||
case GPIO_Key::B10: return {GPIOB,10};
|
|
||||||
case GPIO_Key::B11: return {GPIOB,11};
|
|
||||||
case GPIO_Key::B12: return {GPIOB,12};
|
|
||||||
case GPIO_Key::B13: return {GPIOB,13};
|
|
||||||
case GPIO_Key::B14: return {GPIOB,14};
|
|
||||||
case GPIO_Key::B15: return {GPIOB,15};
|
|
||||||
case GPIO_Key::C0: return {GPIOC,0};
|
|
||||||
case GPIO_Key::C1: return {GPIOC,1};
|
|
||||||
case GPIO_Key::C2: return {GPIOC,2};
|
|
||||||
case GPIO_Key::C3: return {GPIOC,3};
|
|
||||||
case GPIO_Key::C4: return {GPIOC,4};
|
|
||||||
case GPIO_Key::C5: return {GPIOC,5};
|
|
||||||
case GPIO_Key::C6: return {GPIOC,6};
|
|
||||||
case GPIO_Key::C7: return {GPIOC,7};
|
|
||||||
case GPIO_Key::C8: return {GPIOC,8};
|
|
||||||
case GPIO_Key::C9: return {GPIOC,9};
|
|
||||||
case GPIO_Key::C10: return {GPIOC,10};
|
|
||||||
case GPIO_Key::C11: return {GPIOC,11};
|
|
||||||
case GPIO_Key::C12: return {GPIOC,12};
|
|
||||||
case GPIO_Key::C13: return {GPIOC,13};
|
|
||||||
case GPIO_Key::C14: return {GPIOC,14};
|
|
||||||
case GPIO_Key::C15: return {GPIOC,15};
|
|
||||||
case GPIO_Key::INVALID:
|
|
||||||
case GPIO_Key::NUM_GPIO:
|
|
||||||
assert(false);
|
|
||||||
return SHAL_GPIO_Peripheral(nullptr,0); //Unreachable
|
|
||||||
}
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t getGPIOPortNumber(const GPIO_Key g){
|
||||||
|
return (static_cast<uint8_t>(g) / 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
||||||
|
volatile uint32_t* reg = &RCC->AHBENR; //register
|
||||||
|
uint32_t mask;
|
||||||
|
mask = RCC_AHBENR_GPIOAEN << getGPIOPortNumber(g); //Should shift to get each port number
|
||||||
|
|
||||||
|
return {reg,mask};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||||
switch(g) {
|
switch(g) {
|
||||||
case GPIO_Key::A0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PA,EXTI0_1_IRQn};
|
case GPIO_Key::A0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PA,EXTI0_1_IRQn};
|
||||||
@@ -148,128 +111,55 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr SHAL_Peripheral_Register getGPIORCCEnable(const GPIO_Key g){
|
|
||||||
switch(g) {
|
|
||||||
case GPIO_Key::A0:
|
static inline SHAL_GPIO_Mode_Register getGPIOModeRegister(const GPIO_Key key){
|
||||||
case GPIO_Key::A1:
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->MODER;
|
||||||
case GPIO_Key::A2:
|
uint32_t offset = 2 * (static_cast<uint8_t>(key) % 16);
|
||||||
case GPIO_Key::A3:
|
return {reg,offset};
|
||||||
case GPIO_Key::A4:
|
|
||||||
case GPIO_Key::A5:
|
|
||||||
case GPIO_Key::A6:
|
|
||||||
case GPIO_Key::A7:
|
|
||||||
case GPIO_Key::A8:
|
|
||||||
case GPIO_Key::A9:
|
|
||||||
case GPIO_Key::A10:
|
|
||||||
case GPIO_Key::A11:
|
|
||||||
case GPIO_Key::A12:
|
|
||||||
case GPIO_Key::A13:
|
|
||||||
case GPIO_Key::A14:
|
|
||||||
case GPIO_Key::A15:
|
|
||||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOAEN_Pos};
|
|
||||||
case GPIO_Key::B0:
|
|
||||||
case GPIO_Key::B1:
|
|
||||||
case GPIO_Key::B2:
|
|
||||||
case GPIO_Key::B3:
|
|
||||||
case GPIO_Key::B4:
|
|
||||||
case GPIO_Key::B5:
|
|
||||||
case GPIO_Key::B6:
|
|
||||||
case GPIO_Key::B7:
|
|
||||||
case GPIO_Key::B8:
|
|
||||||
case GPIO_Key::B9:
|
|
||||||
case GPIO_Key::B10:
|
|
||||||
case GPIO_Key::B11:
|
|
||||||
case GPIO_Key::B12:
|
|
||||||
case GPIO_Key::B13:
|
|
||||||
case GPIO_Key::B14:
|
|
||||||
case GPIO_Key::B15:
|
|
||||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOBEN_Pos};
|
|
||||||
case GPIO_Key::C0:
|
|
||||||
case GPIO_Key::C1:
|
|
||||||
case GPIO_Key::C2:
|
|
||||||
case GPIO_Key::C3:
|
|
||||||
case GPIO_Key::C4:
|
|
||||||
case GPIO_Key::C5:
|
|
||||||
case GPIO_Key::C6:
|
|
||||||
case GPIO_Key::C7:
|
|
||||||
case GPIO_Key::C8:
|
|
||||||
case GPIO_Key::C9:
|
|
||||||
case GPIO_Key::C10:
|
|
||||||
case GPIO_Key::C11:
|
|
||||||
case GPIO_Key::C12:
|
|
||||||
case GPIO_Key::C13:
|
|
||||||
case GPIO_Key::C14:
|
|
||||||
case GPIO_Key::C15:
|
|
||||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOCEN_Pos};
|
|
||||||
case GPIO_Key::INVALID:
|
|
||||||
case GPIO_Key::NUM_GPIO:
|
|
||||||
assert(false);
|
|
||||||
return SHAL_Peripheral_Register(nullptr,0); //Unreachable
|
|
||||||
}
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){
|
static inline SHAL_GPIO_Pullup_Pulldown_Register getGPIOPUPDRegister(const GPIO_Key key){
|
||||||
switch(g) {
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->PUPDR;
|
||||||
case GPIO_Key::A0:
|
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||||
case GPIO_Key::A1:
|
return {reg,offset};
|
||||||
case GPIO_Key::A2:
|
|
||||||
case GPIO_Key::A3:
|
|
||||||
case GPIO_Key::A4:
|
|
||||||
case GPIO_Key::A5:
|
|
||||||
case GPIO_Key::A6:
|
|
||||||
case GPIO_Key::A7:
|
|
||||||
case GPIO_Key::A8:
|
|
||||||
case GPIO_Key::A9:
|
|
||||||
case GPIO_Key::A10:
|
|
||||||
case GPIO_Key::A11:
|
|
||||||
case GPIO_Key::A12:
|
|
||||||
case GPIO_Key::A13:
|
|
||||||
case GPIO_Key::A14:
|
|
||||||
case GPIO_Key::A15:
|
|
||||||
return 0;
|
|
||||||
case GPIO_Key::B0:
|
|
||||||
case GPIO_Key::B1:
|
|
||||||
case GPIO_Key::B2:
|
|
||||||
case GPIO_Key::B3:
|
|
||||||
case GPIO_Key::B4:
|
|
||||||
case GPIO_Key::B5:
|
|
||||||
case GPIO_Key::B6:
|
|
||||||
case GPIO_Key::B7:
|
|
||||||
case GPIO_Key::B8:
|
|
||||||
case GPIO_Key::B9:
|
|
||||||
case GPIO_Key::B10:
|
|
||||||
case GPIO_Key::B11:
|
|
||||||
case GPIO_Key::B12:
|
|
||||||
case GPIO_Key::B13:
|
|
||||||
case GPIO_Key::B14:
|
|
||||||
case GPIO_Key::B15:
|
|
||||||
return 1;
|
|
||||||
case GPIO_Key::C0:
|
|
||||||
case GPIO_Key::C1:
|
|
||||||
case GPIO_Key::C2:
|
|
||||||
case GPIO_Key::C3:
|
|
||||||
case GPIO_Key::C4:
|
|
||||||
case GPIO_Key::C5:
|
|
||||||
case GPIO_Key::C6:
|
|
||||||
case GPIO_Key::C7:
|
|
||||||
case GPIO_Key::C8:
|
|
||||||
case GPIO_Key::C9:
|
|
||||||
case GPIO_Key::C10:
|
|
||||||
case GPIO_Key::C11:
|
|
||||||
case GPIO_Key::C12:
|
|
||||||
case GPIO_Key::C13:
|
|
||||||
case GPIO_Key::C14:
|
|
||||||
case GPIO_Key::C15:
|
|
||||||
return 2;
|
|
||||||
case GPIO_Key::INVALID:
|
|
||||||
case GPIO_Key::NUM_GPIO:
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_Alternate_Function_Register getGPIOAlternateFunctionRegister(const GPIO_Key key){
|
||||||
|
|
||||||
|
uint32_t pinNumber = static_cast<uint8_t>(key) % 16; //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2)
|
||||||
|
uint32_t afrIndex = pinNumber < 8 ? 0 : 1;
|
||||||
|
|
||||||
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->AFR[afrIndex];
|
||||||
|
uint32_t offset = (pinNumber % 8) * 4; //Increment in groups of four
|
||||||
|
return {reg,offset};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_Output_Speed_Register getGPIOOutputSpeedRegister(const GPIO_Key key){
|
||||||
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OSPEEDR;
|
||||||
|
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||||
|
return {reg,offset};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_Output_Type_Register getGPIOOutputTypeRegister(const GPIO_Key key){
|
||||||
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OTYPER;
|
||||||
|
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||||
|
return {reg,offset};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_Output_Data_Register getGPIOOutputDataRegister(const GPIO_Key key){
|
||||||
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->ODR;
|
||||||
|
uint32_t offset = (static_cast<uint8_t>(key) % 16);
|
||||||
|
return {reg,offset};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_GPIO_Input_Data_Register getGPIOInputDataRegister(const GPIO_Key key){
|
||||||
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->IDR;
|
||||||
|
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||||
|
return {reg,offset};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO reimplement
|
||||||
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
||||||
switch(key){
|
switch(key){
|
||||||
case GPIO_Key::A0:
|
case GPIO_Key::A0:
|
||||||
@@ -343,6 +233,6 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
|||||||
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
||||||
volatile uint32_t* reg = &RCC->AHB2ENR; //register
|
volatile uint32_t* reg = &RCC->AHB2ENR; //register
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
offset = (static_cast<uint8_t>(g) / 16) == 0 ? RCC_AHB2ENR_GPIOAEN_Pos : RCC_AHB2ENR_GPIOBEN_Pos;
|
|
||||||
|
offset = RCC_AHB2ENR_GPIOAEN << getGPIOPortNUmber(g); //Should shift to get each port number
|
||||||
|
|
||||||
return {reg,offset};
|
return {reg,offset};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "SHAL_EXTI_CALLBACK.h"
|
//#include "SHAL_EXTI_CALLBACK.h"
|
||||||
#include "SHAL_ADC.h"
|
//#include "SHAL_ADC.h"
|
||||||
|
|
||||||
|
|
||||||
//Abstraction of SHAL_GPIO registers
|
//Abstraction of SHAL_GPIO registers
|
||||||
@@ -27,12 +27,12 @@ public:
|
|||||||
/// Uses the ADC to read an analog voltage value
|
/// Uses the ADC to read an analog voltage value
|
||||||
/// \param sampleTime The amount of clock cycles to use for the ADC
|
/// \param sampleTime The amount of clock cycles to use for the ADC
|
||||||
/// \return ADC result
|
/// \return ADC result
|
||||||
uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8);
|
//uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8); TODO Reimplement
|
||||||
|
|
||||||
uint16_t digitalRead();
|
uint16_t digitalRead();
|
||||||
|
|
||||||
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
||||||
void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile;
|
//void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile; //TODO reimplement?
|
||||||
|
|
||||||
void setOutputType(PinType type) volatile;
|
void setOutputType(PinType type) volatile;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
|
|
||||||
void setInternalResistor(InternalResistorType type) volatile;
|
void setInternalResistor(InternalResistorType type) volatile;
|
||||||
|
|
||||||
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
|
//void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback); TODO reimplement
|
||||||
|
|
||||||
SHAL_Result setPinMode(PinMode mode) volatile;
|
SHAL_Result setPinMode(PinMode mode) volatile;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ private:
|
|||||||
|
|
||||||
#define GET_GPIO(key) GPIOManager::get(key)
|
#define GET_GPIO(key) GPIOManager::get(key)
|
||||||
|
|
||||||
#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x)
|
//#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x) TODO reimplement
|
||||||
|
|
||||||
|
|
||||||
//Manages instances of SHAL_GPIO objects
|
//Manages instances of SHAL_GPIO objects
|
||||||
@@ -75,9 +75,9 @@ public:
|
|||||||
|
|
||||||
static SHAL_GPIO& get(GPIO_Key);
|
static SHAL_GPIO& get(GPIO_Key);
|
||||||
|
|
||||||
static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;}
|
//static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;} TODO Reimplement
|
||||||
|
|
||||||
static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;}
|
//static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;} TODO Reimplement
|
||||||
|
|
||||||
GPIOManager() = delete;
|
GPIOManager() = delete;
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ private:
|
|||||||
|
|
||||||
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
||||||
|
|
||||||
inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1);
|
//inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1); TODO Reimplement
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#define SHAL_GPIO_TYPES_H
|
#define SHAL_GPIO_TYPES_H
|
||||||
|
|
||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
#include "SHAL_ADC.h"
|
//#include "SHAL_ADC.h"
|
||||||
#include "SHAL_ADC_TYPES.h"
|
//#include "SHAL_ADC_TYPES.h"
|
||||||
|
|
||||||
struct SHAL_GPIO_EXTI_Register{
|
struct SHAL_GPIO_EXTI_Register{
|
||||||
volatile uint32_t* EXT_ICR; //4 32 bit registers which say which GPIO a line is connected to
|
volatile uint32_t* EXT_ICR; //4 32 bit registers which say which GPIO a line is connected to
|
||||||
@@ -17,7 +17,7 @@ struct SHAL_GPIO_EXTI_Register{
|
|||||||
|
|
||||||
struct SHAL_GPIO_RCC_Enable_Register{
|
struct SHAL_GPIO_RCC_Enable_Register{
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
uint32_t offset;
|
uint32_t mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_GPIO_Mode_Register {
|
struct SHAL_GPIO_Mode_Register {
|
||||||
@@ -55,11 +55,12 @@ struct SHAL_GPIO_Input_Data_Register {
|
|||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TODO reimplement and uncomment ADC references (Here and on GPIO.h)
|
||||||
struct SHAL_GPIO_Port_Info{
|
struct SHAL_GPIO_Port_Info{
|
||||||
uint8_t number;
|
uint8_t number;
|
||||||
SHAL_ADC_Channel ADCChannel;
|
SHAL_ADC_Channel ADCChannel;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
enum class PinMode : uint8_t{
|
enum class PinMode : uint8_t{
|
||||||
INPUT_MODE = 0x00,
|
INPUT_MODE = 0x00,
|
||||||
OUTPUT_MODE = 0x01,
|
OUTPUT_MODE = 0x01,
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
#include "SHAL_TIM_TYPES.h"
|
#include "SHAL_TIM_TYPES.h"
|
||||||
|
|
||||||
enum class Timer_Key : uint8_t { //For STM32F072
|
enum class Timer_Key : uint8_t { //For STM32F072
|
||||||
S_TIM1,
|
S_TIM1 = 0,
|
||||||
S_TIM2,
|
S_TIM2 = 1,
|
||||||
S_TIM3,
|
S_TIM3 = 2,
|
||||||
S_TIM6,
|
S_TIM6,
|
||||||
S_TIM7,
|
S_TIM7,
|
||||||
S_TIM14,
|
S_TIM14,
|
||||||
@@ -39,20 +39,40 @@ enum class Timer_Key : uint8_t { //For STM32F072
|
|||||||
#define SHAL_TIM16 TimerManager::get(Timer_Key::S_TIM16)
|
#define SHAL_TIM16 TimerManager::get(Timer_Key::S_TIM16)
|
||||||
#define SHAL_TIM17 TimerManager::get(Timer_Key::S_TIM17)
|
#define SHAL_TIM17 TimerManager::get(Timer_Key::S_TIM17)
|
||||||
|
|
||||||
|
static SHAL_TIM_Info TIM_INFO_TABLE[9] = {
|
||||||
|
{TIM1,TIM1_BRK_UP_TRG_COM_IRQn,4},
|
||||||
|
{TIM2,TIM2_IRQn,4},
|
||||||
|
{TIM3,TIM3_IRQn,4},
|
||||||
|
{TIM6,TIM6_DAC_IRQn,0},
|
||||||
|
{TIM7,TIM7_IRQn,0},
|
||||||
|
{TIM14,TIM14_IRQn,1},
|
||||||
|
{TIM15,TIM15_IRQn,2},
|
||||||
|
{TIM16,TIM16_IRQn,1},
|
||||||
|
{TIM17,TIM17_IRQn,1},
|
||||||
|
};
|
||||||
|
|
||||||
|
//Get actual register value based on enum
|
||||||
|
static volatile TIM_TypeDef* getTimerRegister(Timer_Key t) {
|
||||||
|
return TIM_INFO_TABLE[static_cast<uint8_t>(t)].timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRQn_Type getIRQn(Timer_Key t) {
|
||||||
|
return TIM_INFO_TABLE[static_cast<uint8_t>(t)].IRQn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
||||||
constexpr TIM_RCC_Enable getTimerRCC(Timer_Key t) {
|
static SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
|
||||||
switch(t) {
|
switch(t) {
|
||||||
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos};
|
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN};
|
||||||
case Timer_Key::S_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN_Pos};
|
case Timer_Key::S_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN};
|
||||||
case Timer_Key::S_TIM3: return {&RCC->APB1ENR, RCC_APB1ENR_TIM3EN_Pos};
|
case Timer_Key::S_TIM3: return {&RCC->APB1ENR, RCC_APB1ENR_TIM3EN};
|
||||||
case Timer_Key::S_TIM6: return {&RCC->APB1ENR, RCC_APB1ENR_TIM6EN_Pos};
|
case Timer_Key::S_TIM6: return {&RCC->APB1ENR, RCC_APB1ENR_TIM6EN};
|
||||||
case Timer_Key::S_TIM7: return {&RCC->APB1ENR, RCC_APB1ENR_TIM7EN_Pos};
|
case Timer_Key::S_TIM7: return {&RCC->APB1ENR, RCC_APB1ENR_TIM7EN};
|
||||||
case Timer_Key::S_TIM14: return {&RCC->APB1ENR, RCC_APB1ENR_TIM14EN_Pos};
|
case Timer_Key::S_TIM14: return {&RCC->APB1ENR, RCC_APB1ENR_TIM14EN};
|
||||||
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN_Pos};
|
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN};
|
||||||
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN_Pos};
|
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN};
|
||||||
case Timer_Key::S_TIM17: return {&RCC->APB2ENR, RCC_APB2ENR_TIM17EN_Pos};
|
case Timer_Key::S_TIM17: return {&RCC->APB2ENR, RCC_APB2ENR_TIM17EN};
|
||||||
case Timer_Key::NUM_TIMERS:
|
case Timer_Key::NUM_TIMERS:
|
||||||
case Timer_Key::S_TIM_INVALID:
|
case Timer_Key::S_TIM_INVALID:
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -62,43 +82,161 @@ constexpr TIM_RCC_Enable getTimerRCC(Timer_Key t) {
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get actual register value based on enum
|
|
||||||
constexpr volatile TIM_TypeDef* getTimerRegister(Timer_Key t) {
|
static inline SHAL_TIM_Status_Register getTimerStatusRegister(Timer_Key key){
|
||||||
switch(t) {
|
|
||||||
case Timer_Key::S_TIM1: return TIM1;
|
SHAL_TIM_Status_Register res = {nullptr, TIM_SR_UIF};
|
||||||
case Timer_Key::S_TIM2: return TIM2;
|
|
||||||
case Timer_Key::S_TIM3: return TIM3;
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
case Timer_Key::S_TIM6: return TIM6;
|
|
||||||
case Timer_Key::S_TIM7: return TIM7;
|
res.reg = &tim->SR;
|
||||||
case Timer_Key::S_TIM14: return TIM14;
|
return res;
|
||||||
case Timer_Key::S_TIM15: return TIM15;
|
|
||||||
case Timer_Key::S_TIM16: return TIM16;
|
|
||||||
case Timer_Key::S_TIM17: return TIM17;
|
|
||||||
case Timer_Key::NUM_TIMERS:
|
|
||||||
case Timer_Key::S_TIM_INVALID:
|
|
||||||
assert(false);
|
|
||||||
return nullptr; //Unreachable
|
|
||||||
}
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr IRQn_Type getIRQn(Timer_Key t) {
|
static inline SHAL_TIM_Control_Register_1 getTimerControlRegister1(Timer_Key key){
|
||||||
switch(t) {
|
|
||||||
case Timer_Key::S_TIM1: return TIM1_BRK_UP_TRG_COM_IRQn;
|
SHAL_TIM_Control_Register_1 res = {nullptr, TIM_CR1_CEN_Msk,
|
||||||
case Timer_Key::S_TIM2: return TIM2_IRQn;
|
TIM_CR1_UDIS,
|
||||||
case Timer_Key::S_TIM3: return TIM3_IRQn;
|
TIM_CR1_OPM,
|
||||||
case Timer_Key::S_TIM6: return TIM6_DAC_IRQn;
|
TIM_CR1_CMS_Pos,
|
||||||
case Timer_Key::S_TIM7: return TIM7_IRQn;
|
TIM_CR1_ARPE};
|
||||||
case Timer_Key::S_TIM14: return TIM14_IRQn;
|
|
||||||
case Timer_Key::S_TIM15: return TIM15_IRQn;
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
case Timer_Key::S_TIM16: return TIM16_IRQn;
|
|
||||||
case Timer_Key::S_TIM17: return TIM17_IRQn;
|
res.reg = &tim->CR1;
|
||||||
case Timer_Key::NUM_TIMERS:
|
return res;
|
||||||
case Timer_Key::S_TIM_INVALID:
|
}
|
||||||
assert(false);
|
|
||||||
return TIM1_BRK_UP_TRG_COM_IRQn; //Unreachable
|
static inline SHAL_TIM_DMA_Interrupt_Enable_Register getTimerDMAInterruptEnableRegister(Timer_Key key){
|
||||||
|
|
||||||
|
SHAL_TIM_DMA_Interrupt_Enable_Register res = {nullptr, TIM_DIER_UIE};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->DIER;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Event_Generation_Register getTimerEventGenerationRegister(Timer_Key key){
|
||||||
|
|
||||||
|
SHAL_TIM_Event_Generation_Register res = {nullptr, TIM_EGR_UG};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->EGR;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Break_Dead_Time_Register getTimerBreakDeadTimeRegister(Timer_Key key) {
|
||||||
|
|
||||||
|
SHAL_TIM_Break_Dead_Time_Register res = {nullptr,
|
||||||
|
TIM_BDTR_DTG_Pos,
|
||||||
|
TIM_BDTR_LOCK_Pos,
|
||||||
|
TIM_BDTR_OSSI,
|
||||||
|
TIM_BDTR_OSSR,
|
||||||
|
TIM_BDTR_BKE,
|
||||||
|
TIM_BDTR_BKP,
|
||||||
|
TIM_BDTR_AOE,
|
||||||
|
TIM_BDTR_MOE};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->BDTR;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Prescaler_Register getTimerPrescalerRegister(Timer_Key key){
|
||||||
|
|
||||||
|
SHAL_TIM_Prescaler_Register res = {nullptr, 1UL << 15};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->PSC;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Auto_Reload_Register getTimerAutoReloadRegister(Timer_Key key){
|
||||||
|
|
||||||
|
SHAL_TIM_Auto_Reload_Register res = {nullptr, 1UL << 15};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->ARR;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Capture_Compare_Register getTimerCaptureCompareRegister(Timer_Key key, SHAL_Timer_Channel channel){
|
||||||
|
auto channel_num = static_cast<uint8_t>(channel);
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
assert(channel_num <= TIM_INFO_TABLE[static_cast<uint8_t>(key)].numChannels);
|
||||||
|
|
||||||
|
switch(channel){
|
||||||
|
case SHAL_Timer_Channel::CH1: return {&tim->CCR1,0};
|
||||||
|
case SHAL_Timer_Channel::CH2: return {&tim->CCR2,0};
|
||||||
|
case SHAL_Timer_Channel::CH3: return {&tim->CCR3,0};
|
||||||
|
case SHAL_Timer_Channel::CH4: return {&tim->CCR4,0};
|
||||||
}
|
}
|
||||||
__builtin_unreachable();
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Capture_Compare_Enable_Register getTimerCaptureCompareEnableRegister(Timer_Key key, SHAL_Timer_Channel channel){
|
||||||
|
|
||||||
|
uint8_t channel_stride = 3;
|
||||||
|
auto channel_num = static_cast<uint8_t>(channel);
|
||||||
|
|
||||||
|
auto output_enable = TIM_CCER_CC1E << (channel_stride * (channel_num - 1));
|
||||||
|
auto output_polarity = TIM_CCER_CC1P << (channel_stride * channel_num);
|
||||||
|
auto output_complimentary_enable = TIM_CCER_CC1NE << (channel_stride * channel_num);
|
||||||
|
auto output_complimentary_polarity = TIM_CCER_CC1NP << (channel_stride * channel_num);
|
||||||
|
|
||||||
|
SHAL_TIM_Capture_Compare_Enable_Register res = {nullptr,
|
||||||
|
output_enable,
|
||||||
|
output_polarity,
|
||||||
|
output_complimentary_enable,
|
||||||
|
output_complimentary_polarity,
|
||||||
|
};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
|
||||||
|
res.reg = &tim->CCER;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SHAL_TIM_Output_Capture_Compare_Mode_Register getTimerOutputCaptureCompareModeRegister(Timer_Key key, SHAL_Timer_Channel channel) {
|
||||||
|
SHAL_TIM_Output_Capture_Compare_Mode_Register res = {
|
||||||
|
nullptr,
|
||||||
|
TIM_CCMR1_CC1S_Pos, //Channel 1 Capture/Compare selection
|
||||||
|
TIM_CCMR1_OC1FE, //Channel 1 Fast enable
|
||||||
|
TIM_CCMR1_OC1PE, //Channel 1 Preload enable
|
||||||
|
TIM_CCMR1_OC1M_Pos, //Channel 1 Mode (OC1M)
|
||||||
|
TIM_CCMR1_OC1CE, //Channel 1 Clear enable
|
||||||
|
TIM_CCMR1_CC2S_Pos, //Channel 2 Capture/Compare selection
|
||||||
|
TIM_CCMR1_OC2FE, //Channel 2 Fast enable
|
||||||
|
TIM_CCMR1_OC2PE, //Channel 2 Preload enable
|
||||||
|
TIM_CCMR1_OC2M_Pos, //Channel 2 Mode (OC2M)
|
||||||
|
TIM_CCMR1_OC2CE //Channel 2 Clear enable
|
||||||
|
};
|
||||||
|
|
||||||
|
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||||
|
uint8_t num_tim_channels = TIM_INFO_TABLE[static_cast<uint8_t>(key)].numChannels;
|
||||||
|
|
||||||
|
volatile uint32_t* reg = nullptr;
|
||||||
|
|
||||||
|
uint8_t channelNum = static_cast<uint32_t>(channel);
|
||||||
|
|
||||||
|
assert(num_tim_channels >= channelNum); //Assert that we don't access undefined memory trying to initialize a non-existent channel
|
||||||
|
|
||||||
|
if(channelNum >= 3){
|
||||||
|
reg = &tim->CCMR2;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
reg = &tim->CCMR1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.reg = reg;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ public:
|
|||||||
//Enable interrupts
|
//Enable interrupts
|
||||||
void enableInterrupt();
|
void enableInterrupt();
|
||||||
|
|
||||||
void setPWMMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
//Capture Compare Functions
|
||||||
|
void setCaptureCompareValue(SHAL_Timer_Channel channel, uint16_t value);
|
||||||
|
void enableChannel(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
||||||
|
void setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode);
|
||||||
|
|
||||||
/// Set the duty cycle for PWM
|
/// Set the duty cycle for PWM
|
||||||
/// \param dutyCycle 10 * percentage (e.g. 500 = 50%)
|
/// \param dutyCycle 10 * percentage (e.g. 500 = 50%)
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
|
|
||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
|
|
||||||
|
struct SHAL_TIM_Info{
|
||||||
|
volatile TIM_TypeDef* timer;
|
||||||
|
IRQn_Type IRQn;
|
||||||
|
uint8_t numChannels;
|
||||||
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_RCC_Register{
|
struct SHAL_TIM_RCC_Register{
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
uint32_t enable_mask;
|
uint32_t enable_mask;
|
||||||
@@ -47,7 +53,7 @@ struct SHAL_TIM_Auto_Reload_Register {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
||||||
volatile uint32_t* regs[2];
|
volatile uint32_t* regs;
|
||||||
uint32_t input_capture_1_filter_offset;
|
uint32_t input_capture_1_filter_offset;
|
||||||
uint32_t input_capture_1_prescaler_offset;
|
uint32_t input_capture_1_prescaler_offset;
|
||||||
uint32_t capture_compare_1_selection_offset;
|
uint32_t capture_compare_1_selection_offset;
|
||||||
@@ -56,8 +62,8 @@ struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
|||||||
uint32_t capture_compare_2_selection_offset;
|
uint32_t capture_compare_2_selection_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
struct SHAL_TIM_Output_Capture_Compare_Mode_Register {
|
||||||
volatile uint32_t* regs[2];
|
volatile uint32_t* reg;
|
||||||
uint32_t capture_compare_1_selection_offset;
|
uint32_t capture_compare_1_selection_offset;
|
||||||
uint32_t output_compare_1_fast_enable_mask;
|
uint32_t output_compare_1_fast_enable_mask;
|
||||||
uint32_t output_compare_1_preload_enable_mask;
|
uint32_t output_compare_1_preload_enable_mask;
|
||||||
@@ -72,15 +78,27 @@ struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
|||||||
|
|
||||||
struct SHAL_TIM_Break_Dead_Time_Register {
|
struct SHAL_TIM_Break_Dead_Time_Register {
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
uint32_t main_output_enable_mask;
|
uint32_t dead_time_offset; // [7:0] DTG - Dead-time generator setup
|
||||||
|
uint32_t lock_configuration_offset; // [9:8] LOCK - Lock configuration
|
||||||
|
uint32_t off_state_selection_idle_mask; // [10] OSSI - Off-state selection for idle mode
|
||||||
|
uint32_t off_state_selection_run_mask; // [11] OSSR - Off-state selection for run mode
|
||||||
|
uint32_t break_enable_mask; // [12] BKE - Break enable
|
||||||
|
uint32_t break_polarity_mask; // [13] BKP - Break polarity
|
||||||
|
uint32_t automatic_output_enable_mask; // [14] AOE - Automatic output enable
|
||||||
|
uint32_t main_output_enable_mask; // [15] MOE - Main output enable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Capture_Compare_Enable_Register {
|
struct SHAL_TIM_Capture_Compare_Enable_Register {
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
|
uint32_t cc_output_enable_offset;
|
||||||
|
uint32_t cc_output_polarity_offset;
|
||||||
|
uint32_t cc_complimentary_output_enable_offset;
|
||||||
|
uint32_t cc_complimentary_output_polarity_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Capture_Compare_Register {
|
struct SHAL_TIM_Capture_Compare_Register {
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -102,12 +120,10 @@ enum class SHAL_TIM_Output_Compare_Preload : uint8_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class SHAL_Timer_Channel : uint8_t { //TODO change if other timers have fewer than 6 channels
|
enum class SHAL_Timer_Channel : uint8_t { //TODO change if other timers have fewer than 6 channels
|
||||||
CH1 = 0,
|
CH1 = 1,
|
||||||
CH2 = 1,
|
CH2 = 2,
|
||||||
CH3 = 2,
|
CH3 = 3,
|
||||||
CH4 = 3,
|
CH4 = 4,
|
||||||
CH5 = 4,
|
|
||||||
CH6 = 5,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SHAL_Timer_Channel_Main_Output_Mode : uint8_t {
|
enum class SHAL_Timer_Channel_Main_Output_Mode : uint8_t {
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
#include "SHAL_GPIO_REG.h"
|
#include "SHAL_GPIO_REG.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Represents a pair of pins usable for USART Tx + Rx in combination, and their alternate function mapping
|
//Represents a pair of pins usable for USART Tx + Rx in combination, and their alternate function mapping
|
||||||
struct SHAL_UART_Pair{
|
struct SHAL_UART_Pair{
|
||||||
USART_TypeDef* USARTReg;
|
USART_TypeDef* USARTReg;
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
#include "SHAL_TIM.h"
|
#include "SHAL_TIM.h"
|
||||||
#include "SHAL_GPIO.h"
|
#include "SHAL_GPIO.h"
|
||||||
#include "SHAL_UART.h"
|
//#include "SHAL_UART.h"
|
||||||
#include "SHAL_ADC.h"
|
//#include "SHAL_ADC.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "SHAL_ADC.h"
|
#include "SHAL_ADC.h"
|
||||||
|
|
||||||
//Can hard code registers on F0 because all F0 devices have only one ADC, and use only one clock
|
//Can hard code registers on F0 because all F0 devices have only one ADC, and use only one clock
|
||||||
SHAL_Result SHAL_ADC::init() {
|
SHAL_Result SHAL_ADC::init(ADC_Key key) {
|
||||||
|
|
||||||
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
|
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
|
||||||
return SHAL_Result::ERROR;
|
return SHAL_Result::ERROR;
|
||||||
@@ -81,7 +81,7 @@ uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, SHAL_ADC_Sample
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) {
|
SHAL_Result SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) {
|
||||||
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
||||||
|
|
||||||
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
|
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "SHAL_GPIO.h"
|
#include "SHAL_GPIO.h"
|
||||||
#include "SHAL_EXTI_CALLBACK.h"
|
//#include "SHAL_EXTI_CALLBACK.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,10 +13,9 @@ SHAL_GPIO::SHAL_GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
|
|||||||
|
|
||||||
SHAL_GPIO::SHAL_GPIO(GPIO_Key key) : m_GPIO_KEY(key) {
|
SHAL_GPIO::SHAL_GPIO(GPIO_Key key) : m_GPIO_KEY(key) {
|
||||||
|
|
||||||
volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg;
|
auto GPIORCCEnable = getGPIORCCEnable(key);
|
||||||
unsigned long gpioOffset = getGPIORCCEnable(key).offset;
|
|
||||||
|
|
||||||
*gpioEnable |= (1 << gpioOffset); //Set enable flag
|
SHAL_set_register_value(GPIORCCEnable.reg,GPIORCCEnable.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_GPIO::setLow() {
|
void SHAL_GPIO::setLow() {
|
||||||
@@ -54,12 +53,23 @@ void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function AF) volatile {
|
|||||||
SHAL_set_bits(alternateFunctionReg.reg,4,static_cast<uint8_t>(AF),alternateFunctionReg.offset);
|
SHAL_set_bits(alternateFunctionReg.reg,4,static_cast<uint8_t>(AF),alternateFunctionReg.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_GPIO::setPinMode(PinMode mode) volatile {
|
SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) volatile {
|
||||||
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
|
auto pinModeReg = getGPIOModeRegister(m_GPIO_KEY);
|
||||||
gpioPeripheral.reg->MODER &= ~(0x03 << (2 * gpioPeripheral.global_offset)); //Clear any previous mode
|
|
||||||
gpioPeripheral.reg->MODER |= (static_cast<uint8_t>(mode) << (2 * gpioPeripheral.global_offset)); //Set mode based on pinmode bit structure
|
/*
|
||||||
|
if(mode == PinMode::ANALOG_MODE && getGPIOPortInfo(m_GPIO_KEY).ADCChannel == SHAL_ADC_Channel::NO_ADC_MAPPING){
|
||||||
|
char buff[100];
|
||||||
|
sprintf(buff, "Error: GPIO pin %d has no valid ADC mapping\r\n", static_cast<uint8_t>(m_GPIO_KEY));
|
||||||
|
SHAL_UART2.sendString(buff);
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
SHAL_set_bits(pinModeReg.reg,2,static_cast<uint8_t>(mode),pinModeReg.offset); //Set mode
|
||||||
|
|
||||||
|
return SHAL_Result::OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO Fix implementation for STM32F072
|
||||||
void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) {
|
void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) {
|
||||||
|
|
||||||
uint32_t gpioPin = getGPIORegister(m_GPIO_KEY).global_offset; //Use existing structs to get offset
|
uint32_t gpioPin = getGPIORegister(m_GPIO_KEY).global_offset; //Use existing structs to get offset
|
||||||
@@ -98,23 +108,25 @@ void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback)
|
|||||||
|
|
||||||
__enable_irq(); //Enable IRQ just in case
|
__enable_irq(); //Enable IRQ just in case
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO reimplement
|
||||||
uint16_t SHAL_GPIO::analogRead(SHAL_ADC_SampleTime sampleTime) {
|
uint16_t SHAL_GPIO::analogRead(SHAL_ADC_SampleTime sampleTime) {
|
||||||
|
|
||||||
SHAL_ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel;
|
SHAL_ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel;
|
||||||
|
|
||||||
return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime);
|
return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
SHAL_GPIO& GPIOManager::get(GPIO_Key key) {
|
SHAL_GPIO& GPIOManager::get(GPIO_Key key) {
|
||||||
|
|
||||||
unsigned int gpioPort = getGPIOPortNumber(key);
|
unsigned int gpioPort = getGPIOPortNumber(key);
|
||||||
unsigned long gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset
|
uint8_t gpioPin = getGPIOPinNumber(key);
|
||||||
|
|
||||||
if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){
|
if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){
|
||||||
m_gpios[gpioPort][gpioPin] = SHAL_GPIO(key);
|
m_gpios[gpioPort][gpioPin] = SHAL_GPIO(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_gpios[gpioPort][gpioPin];
|
return m_gpios[gpioPort][gpioPin];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,6 @@ void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t wri
|
|||||||
//Read phase
|
//Read phase
|
||||||
if (readLen > 0) {
|
if (readLen > 0) {
|
||||||
|
|
||||||
SHAL_UART2.sendString("Read initiated\r\n");
|
|
||||||
|
|
||||||
I2CPeripheral->CR2 &= ~(I2C_CR2_NBYTES | I2C_CR2_SADD | I2C_CR2_RD_WRN);
|
I2CPeripheral->CR2 &= ~(I2C_CR2_NBYTES | I2C_CR2_SADD | I2C_CR2_RD_WRN);
|
||||||
I2CPeripheral->CR2 |= (addr << 1) |
|
I2CPeripheral->CR2 |= (addr << 1) |
|
||||||
I2C_CR2_RD_WRN |
|
I2C_CR2_RD_WRN |
|
||||||
|
|||||||
@@ -5,45 +5,96 @@
|
|||||||
#include "SHAL_TIM.h"
|
#include "SHAL_TIM.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
Timer::Timer(Timer_Key t) : TIMER_KEY(t){
|
Timer::Timer(Timer_Key t) : m_key(t){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){
|
Timer::Timer() : m_key(Timer_Key::S_TIM_INVALID){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::start() {
|
void Timer::start() {
|
||||||
getTimerRegister(TIMER_KEY)->CR1 |= TIM_CR1_CEN;
|
|
||||||
getTimerRegister(TIMER_KEY)->EGR |= TIM_EGR_UG; //load prescaler reg and ARR
|
auto control_reg = getTimerControlRegister1(m_key);
|
||||||
|
auto event_generation_reg = getTimerEventGenerationRegister(m_key);
|
||||||
|
auto status_reg = getTimerStatusRegister(m_key);
|
||||||
|
auto break_time_dead_reg = getTimerBreakDeadTimeRegister(m_key);
|
||||||
|
|
||||||
|
auto rcc_reg = getTimerRCC(m_key);
|
||||||
|
|
||||||
|
SHAL_apply_bitmask(control_reg.reg, control_reg.counter_enable_mask); //Enable counter
|
||||||
|
SHAL_apply_bitmask(control_reg.reg, control_reg.auto_reload_preload_enable_mask); //Preload enable (buffer)
|
||||||
|
SHAL_apply_bitmask(event_generation_reg.reg, event_generation_reg.update_generation_mask);
|
||||||
|
|
||||||
|
SHAL_clear_bitmask(status_reg.reg,status_reg.update_interrupt_flag_mask);
|
||||||
|
|
||||||
|
SHAL_apply_bitmask(rcc_reg.reg,rcc_reg.enable_mask);
|
||||||
|
SHAL_apply_bitmask(break_time_dead_reg.reg,break_time_dead_reg.main_output_enable_mask);
|
||||||
|
|
||||||
enableInterrupt();
|
enableInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::stop() {
|
void Timer::stop() {
|
||||||
getTimerRegister(TIMER_KEY)->CR1 &= ~TIM_CR1_CEN;
|
auto rcc_reg = getTimerRCC(m_key);
|
||||||
|
|
||||||
|
SHAL_clear_bitmask(rcc_reg.reg,rcc_reg.enable_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::setPrescaler(uint16_t presc) {
|
void Timer::setPrescaler(uint16_t presc) {
|
||||||
getTimerRegister(TIMER_KEY)->PSC = presc;
|
getTimerRegister(m_key)->PSC = presc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::setARR(uint16_t arr) {
|
void Timer::setARR(uint16_t arr) {
|
||||||
getTimerRegister(TIMER_KEY)->ARR = arr;
|
getTimerRegister(m_key)->ARR = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::enableInterrupt() {
|
void Timer::enableInterrupt() {
|
||||||
getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
|
getTimerRegister(m_key)->DIER |= TIM_DIER_UIE;
|
||||||
NVIC_EnableIRQ(getIRQn(TIMER_KEY));
|
NVIC_EnableIRQ(getIRQn(m_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::init(uint32_t prescaler, uint32_t autoReload) {
|
void Timer::init(uint16_t prescaler, uint16_t autoReload) {
|
||||||
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
|
SHAL_TIM_RCC_Register rcc = getTimerRCC(m_key);
|
||||||
*rcc.busEnableReg |= (1 << rcc.offset);
|
|
||||||
|
SHAL_apply_bitmask(rcc.reg,rcc.enable_mask);
|
||||||
|
|
||||||
setPrescaler(prescaler);
|
setPrescaler(prescaler);
|
||||||
setARR(autoReload);
|
setARR(autoReload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timer::setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode) {
|
||||||
|
|
||||||
|
auto channelNum = static_cast<uint8_t>(channel);
|
||||||
|
|
||||||
|
auto CCMR = getTimerOutputCaptureCompareModeRegister(m_key, channel);
|
||||||
|
|
||||||
|
uint32_t OCMR_Offset = channelNum % 2 == 1 ? CCMR.output_compare_1_mode_offset : CCMR.output_compare_2_mode_offset;
|
||||||
|
|
||||||
|
SHAL_set_bits(CCMR.reg,3,static_cast<uint8_t>(outputCompareMode),OCMR_Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::enableChannel(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode,
|
||||||
|
SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode) {
|
||||||
|
|
||||||
|
SHAL_TIM_Capture_Compare_Enable_Register captureCompareEnableReg = getTimerCaptureCompareEnableRegister(m_key, channel);
|
||||||
|
|
||||||
|
uint16_t setValue = 0; //Value to set the register as
|
||||||
|
auto channelNum = static_cast<uint8_t>(channel);
|
||||||
|
|
||||||
|
uint8_t channelStride = 4; //4 bits per field
|
||||||
|
|
||||||
|
setValue |= (static_cast<uint8_t>(mainOutputMode) << ((channelNum - 1) * channelStride)); //xxBB shifted by c - 1
|
||||||
|
setValue |= (static_cast<uint8_t>(complimentaryOutputMode) << (((channelNum - 1) * channelStride) + 2)); //BBxx shifted by c - 1
|
||||||
|
|
||||||
|
SHAL_set_bits(captureCompareEnableReg.reg,16,setValue,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::setCaptureCompareValue(SHAL_Timer_Channel channel, uint16_t value) {
|
||||||
|
auto captureCompareReg = getTimerCaptureCompareRegister(m_key,channel);
|
||||||
|
|
||||||
|
SHAL_set_bits(captureCompareReg.reg,16,value,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Timer &TimerManager::get(Timer_Key timer_key) {
|
Timer &TimerManager::get(Timer_Key timer_key) {
|
||||||
|
|
||||||
@@ -53,11 +104,9 @@ Timer &TimerManager::get(Timer_Key timer_key) {
|
|||||||
Timer& selected = timers[static_cast<int>(timer_key)];
|
Timer& selected = timers[static_cast<int>(timer_key)];
|
||||||
|
|
||||||
//Timer queried is not initialized yet (defaults to invalid)
|
//Timer queried is not initialized yet (defaults to invalid)
|
||||||
if(selected.TIMER_KEY == Timer_Key::S_TIM_INVALID){
|
if(selected.m_key == Timer_Key::S_TIM_INVALID){
|
||||||
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
|
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
|
||||||
}
|
}
|
||||||
|
|
||||||
return timers[static_cast<int>(timer_key)];
|
return timers[static_cast<int>(timer_key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, SHAL_ADC_Sample
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAL_Result SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) {
|
SHAL_Result SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) {
|
||||||
auto data_reg = getADCDataReg(m_ADCKey); //Where our output will be stored
|
auto data_reg = getADCDataReg(m_ADCKey); //Where our output will be stored
|
||||||
|
|
||||||
setADCSequenceAmount(numChannels); //Convert the correct amount of channels
|
setADCSequenceAmount(numChannels); //Convert the correct amount of channels
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t wri
|
|||||||
|
|
||||||
for (size_t i = 0; i < writeLen; i++) {
|
for (size_t i = 0; i < writeLen; i++) {
|
||||||
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TXIS) != 0, 100)){
|
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TXIS) != 0, 100)){
|
||||||
SHAL_UART2.sendString("I2C timed out waiting for TX\r\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
I2CPeripheral->TXDR = writeData[i];
|
I2CPeripheral->TXDR = writeData[i];
|
||||||
|
|||||||
@@ -1,264 +1,19 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "SHAL.h"
|
#include "SHAL.h"
|
||||||
|
|
||||||
|
|
||||||
#define NUM_CHANNELS 6
|
|
||||||
|
|
||||||
// Physical order on right-side header: A0, A1, A3, A4, A5, A6, A7
|
|
||||||
SHAL_ADC_Channel channels[NUM_CHANNELS] = {
|
|
||||||
SHAL_ADC_Channel::CH5,
|
|
||||||
SHAL_ADC_Channel::CH6,
|
|
||||||
SHAL_ADC_Channel::CH8,
|
|
||||||
SHAL_ADC_Channel::CH9,
|
|
||||||
SHAL_ADC_Channel::CH10,
|
|
||||||
SHAL_ADC_Channel::CH12,
|
|
||||||
};
|
|
||||||
|
|
||||||
bool isDeviceOn = false;
|
|
||||||
bool shouldToggleDeviceState = true;
|
|
||||||
bool shouldCheckSensorThresholds = true;
|
|
||||||
|
|
||||||
uint16_t vals[NUM_CHANNELS] = {0,0,0,0,0,0};
|
|
||||||
uint8_t currentSensor = 0;
|
|
||||||
|
|
||||||
bool isAlarmBeeping = false;
|
|
||||||
|
|
||||||
uint16_t sensorThresholds[NUM_CHANNELS] = {0,0,0,0,0,0};
|
|
||||||
|
|
||||||
int buzzer_beepCount = 0;
|
|
||||||
bool isBeepingForCalibration = false;
|
|
||||||
|
|
||||||
bool prevIsCalibrateButtonHigh = false;
|
|
||||||
|
|
||||||
int cyclesPerPrint = 2;
|
|
||||||
int currentCycle = 0;
|
|
||||||
|
|
||||||
bool areSensorRequirementsMetCurrent = false;
|
|
||||||
bool areSensorRequirementsMetPrevious = false;
|
|
||||||
|
|
||||||
void getSensorData(){
|
|
||||||
|
|
||||||
vals[currentSensor] = SHAL_ADC1.singleConvertSingle(channels[currentSensor]);
|
|
||||||
|
|
||||||
if(currentSensor == (NUM_CHANNELS - 1) && currentCycle == cyclesPerPrint - 1){
|
|
||||||
char buff[125];
|
|
||||||
// Print in the same order as the channels[] array (physical order)
|
|
||||||
sprintf(buff, "A0:%u,A1:%u,A3:%u,A4:%u,A5:%u,A6:%u\r\n",
|
|
||||||
vals[0], vals[1], vals[2], vals[3], vals[4], vals[5]);
|
|
||||||
SHAL_UART2.sendString(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentSensor = (currentSensor + 1) % NUM_CHANNELS;
|
|
||||||
currentCycle = (currentCycle + 1) % cyclesPerPrint;
|
|
||||||
}
|
|
||||||
|
|
||||||
void startBeeping(){
|
|
||||||
|
|
||||||
SHAL_TIM6.setPrescaler(4000);
|
|
||||||
SHAL_TIM6.setARR(200);
|
|
||||||
|
|
||||||
SHAL_TIM6.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopBeeping(){
|
|
||||||
SHAL_TIM1.stop();
|
|
||||||
SHAL_TIM6.stop();
|
|
||||||
isAlarmBeeping = false;
|
|
||||||
isBeepingForCalibration = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkSensorThresholds(){
|
|
||||||
|
|
||||||
bool localFlag = true;
|
|
||||||
|
|
||||||
for(int i = 0; i < NUM_CHANNELS; i++){
|
|
||||||
if(vals[i] < sensorThresholds[i]){
|
|
||||||
areSensorRequirementsMetCurrent = false; //Conditions not met
|
|
||||||
localFlag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(localFlag){
|
|
||||||
areSensorRequirementsMetCurrent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(areSensorRequirementsMetCurrent){
|
|
||||||
if(!areSensorRequirementsMetPrevious){
|
|
||||||
SHAL_TIM1.stop();
|
|
||||||
SHAL_TIM6.stop();
|
|
||||||
SHAL_TIM15.stop();
|
|
||||||
PIN(A9).setLow();
|
|
||||||
stopBeeping();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(areSensorRequirementsMetPrevious){
|
|
||||||
SHAL_TIM15.start();
|
|
||||||
PIN(A9).setHigh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
areSensorRequirementsMetPrevious = areSensorRequirementsMetCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calibrateThresholds(){
|
|
||||||
|
|
||||||
// Read every channel once and set threshold to 80% of reading
|
|
||||||
for(int i = 0; i < NUM_CHANNELS; i++){
|
|
||||||
uint16_t sensorVal = (vals[i] * 3) / 5;
|
|
||||||
|
|
||||||
if(sensorVal < 50){
|
|
||||||
sensorVal = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
sensorVal = sensorVal - 50;
|
|
||||||
}
|
|
||||||
sensorThresholds[i] = sensorVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buff[125];
|
|
||||||
// Print in the same order as the channels[] array (physical order)
|
|
||||||
sprintf(buff, "Thresholds calibrated to: A0:%u,A1:%u,A3:%u,A4:%u,A5:%u,A6:%u\r\n",
|
|
||||||
sensorThresholds[0], sensorThresholds[1], sensorThresholds[2], sensorThresholds[3], sensorThresholds[4], sensorThresholds[5]);
|
|
||||||
SHAL_UART2.sendString(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PWMToggle(){
|
|
||||||
|
|
||||||
//Flash light
|
|
||||||
PIN(A9).toggle();
|
|
||||||
|
|
||||||
SHAL_TIM15.stop(); //Stop timer for allowed time off sensors
|
|
||||||
|
|
||||||
if(isBeepingForCalibration && buzzer_beepCount > 2){
|
|
||||||
isBeepingForCalibration = false;
|
|
||||||
buzzer_beepCount = 0;
|
|
||||||
SHAL_TIM6.stop(); //Reset timer 6
|
|
||||||
SHAL_TIM1.stop(); //Stop buzzer
|
|
||||||
|
|
||||||
SHAL_TIM6.setPrescaler(4000);
|
|
||||||
SHAL_TIM6.setARR(400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isAlarmBeeping){
|
|
||||||
SHAL_TIM1.start();
|
|
||||||
buzzer_beepCount++;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
SHAL_TIM1.stop();
|
|
||||||
}
|
|
||||||
isAlarmBeeping = !isAlarmBeeping;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buttonHoldCallback(){
|
|
||||||
|
|
||||||
shouldCheckSensorThresholds = false; //Dont check sensor thresholds yet, ensure that calibration beep happens
|
|
||||||
|
|
||||||
SHAL_TIM7.stop(); //Stop this timer
|
|
||||||
|
|
||||||
SHAL_TIM2.stop(); //Stop reading from ADC
|
|
||||||
|
|
||||||
buzzer_beepCount = 0;
|
|
||||||
isBeepingForCalibration = true;
|
|
||||||
|
|
||||||
SHAL_TIM6.init(4000,50);
|
|
||||||
SHAL_TIM6.start();
|
|
||||||
|
|
||||||
calibrateThresholds();
|
|
||||||
SHAL_TIM1.start();
|
|
||||||
|
|
||||||
SHAL_TIM2.start(); //Restart value checks
|
|
||||||
|
|
||||||
shouldToggleDeviceState = false;
|
|
||||||
shouldCheckSensorThresholds = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
SHAL_init();
|
SHAL_init();
|
||||||
|
|
||||||
//SHAL_UART2.init(UART_Pair_Key::Tx2A2_Rx2A3);
|
PIN(A8).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
|
||||||
//SHAL_UART2.begin(115200);
|
|
||||||
|
|
||||||
PIN(A0).setPinMode(PinMode::ANALOG_MODE);
|
PIN(A8).setAlternateFunction(GPIO_Alternate_Function::AF2);
|
||||||
PIN(A1).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
PIN(A3).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
PIN(A4).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
PIN(A5).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
PIN(A6).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
PIN(A7).setPinMode(PinMode::ANALOG_MODE);
|
|
||||||
|
|
||||||
PIN(B6).setPinMode(PinMode::INPUT_MODE);
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||||
PIN(A9).setPinMode(PinMode::OUTPUT_MODE);
|
|
||||||
PIN(B0).setAlternateFunction(GPIO_Alternate_Function_Mapping::B0_TIM1CH2N);
|
|
||||||
|
|
||||||
PIN(A8).setPinMode(PinMode::OUTPUT_MODE);
|
SHAL_TIM1.init(48,100);
|
||||||
PIN(A8).setInternalResistor(InternalResistorType::NO_PULL);
|
SHAL_TIM1.setOutputCompareMode(SHAL_Timer_Channel::CH1,SHAL_TIM_Output_Compare_Mode::PWMMode1);
|
||||||
|
SHAL_TIM1.enableChannel(SHAL_Timer_Channel::CH1,SHAL_Timer_Channel_Main_Output_Mode::Polarity_Reversed,SHAL_Timer_Channel_Complimentary_Output_Mode::Disabled);
|
||||||
SHAL_TIM2.init(4000,200);
|
SHAL_TIM1.setCaptureCompareValue(SHAL_Timer_Channel::CH1, 5);
|
||||||
|
SHAL_TIM1.start();
|
||||||
SHAL_TIM2.setCallbackFunc(getSensorData);
|
|
||||||
SHAL_TIM2.enableInterrupt();
|
|
||||||
SHAL_TIM2.start();
|
|
||||||
|
|
||||||
SHAL_TIM1.init(0,2400); //PWM signal
|
|
||||||
SHAL_TIM1.setPWMMode(SHAL_Timer_Channel::CH2,SHAL_TIM_Output_Compare_Mode::PWMMode1,SHAL_Timer_Channel_Main_Output_Mode::Polarity_Normal,SHAL_Timer_Channel_Complimentary_Output_Mode::Polarity_Reversed);
|
|
||||||
SHAL_TIM1.setPWMDutyCycle(900);
|
|
||||||
|
|
||||||
SHAL_TIM6.init(4000,500); //PWM switcher
|
|
||||||
SHAL_TIM6.setCallbackFunc(PWMToggle);
|
|
||||||
SHAL_TIM6.enableInterrupt();
|
|
||||||
|
|
||||||
SHAL_TIM7.init(4000,3000); //Calibrate timer
|
|
||||||
SHAL_TIM7.setCallbackFunc(buttonHoldCallback);
|
|
||||||
SHAL_TIM7.enableInterrupt();
|
|
||||||
|
|
||||||
SHAL_TIM15.init(4000,5000); //5 seconds
|
|
||||||
SHAL_TIM15.setCallbackFunc(startBeeping);
|
|
||||||
SHAL_TIM15.enableInterrupt();
|
|
||||||
|
|
||||||
|
|
||||||
SHAL_UART2.sendString("Hello3\r\n");
|
|
||||||
|
|
||||||
while (true) { //TODO set to use button for simulating off sensor, uncomment for real functionality
|
|
||||||
|
|
||||||
if(PIN(B6).digitalRead() != 1){
|
|
||||||
|
|
||||||
if(prevIsCalibrateButtonHigh){
|
|
||||||
SHAL_TIM7.start();
|
|
||||||
}
|
|
||||||
prevIsCalibrateButtonHigh = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(!prevIsCalibrateButtonHigh){
|
|
||||||
if(shouldToggleDeviceState){
|
|
||||||
if(!isDeviceOn){ //Turn device on
|
|
||||||
PIN(A8).setHigh();
|
|
||||||
isDeviceOn = true;
|
|
||||||
}
|
|
||||||
else{ //Turn device off
|
|
||||||
PIN(A8).setLow();
|
|
||||||
PIN(A9).setLow();
|
|
||||||
isDeviceOn = false;
|
|
||||||
|
|
||||||
areSensorRequirementsMetCurrent = true;
|
|
||||||
areSensorRequirementsMetPrevious = true;
|
|
||||||
|
|
||||||
SHAL_TIM15.stop();
|
|
||||||
stopBeeping();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldToggleDeviceState = true;
|
|
||||||
|
|
||||||
SHAL_TIM7.stop();
|
|
||||||
}
|
|
||||||
prevIsCalibrateButtonHigh = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isDeviceOn && shouldCheckSensorThresholds){
|
|
||||||
checkSensorThresholds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc)
|
|||||||
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
|
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
|
||||||
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)
|
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)
|
||||||
|
|
||||||
set(COMMON_FLAGS "-mcpu=cortex-m4 -mthumb -fdata-sections -ffunction-sections")
|
set(COMMON_FLAGS "-mcpu=cortex-m0 -mthumb -fdata-sections -ffunction-sections")
|
||||||
set(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} --specs=nano.specs")
|
set(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} --specs=nano.specs")
|
||||||
set(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics --specs=nano.specs")
|
set(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics --specs=nano.specs")
|
||||||
|
|
||||||
|
|||||||
BIN
shmingo-HAL.bin
Normal file
BIN
shmingo-HAL.bin
Normal file
Binary file not shown.
BIN
shmingo-HAL.elf
Normal file
BIN
shmingo-HAL.elf
Normal file
Binary file not shown.
1265
shmingo-HAL.hex
Normal file
1265
shmingo-HAL.hex
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user