diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6aeb086..3368a41 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,18 +7,16 @@ set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
enable_language(C ASM CXX)
-set(MCU_FAMILY "STM32H7xx")
-set(MCU_MODEL "STM32H753xx")
+set(MCU_FAMILY "STM32F0xx")
+set(MCU_MODEL "STM32F072xB")
set(CPU_PARAMETERS
- -mcpu=cortex-m7
- -mfpu=fpv5-d16
- -mfloat-abi=hard
+ -mcpu=cortex-m0
)
-set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/H753ZIT6/startup_stm32h753xx.S
+set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/F030x6/startup_stm32f030x6.S
SHAL/Src/User_Config.h)
-set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/H753ZIT6/stm32h753zitx_flash.ld)
+set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/F030x6/STM32F030XX_FLASH.ld)
set(EXECUTABLE ${CMAKE_PROJECT_NAME})
enable_language(C CXX ASM)
@@ -49,10 +47,6 @@ SHAL/Include/Peripheral/EXT/Reg
SHAL/Include/Peripheral/GPIO/Reg
SHAL/Include/Peripheral/Timer
SHAL/Include/Peripheral/Timer/Reg
- SHAL/Include/Peripheral/UART
- SHAL/Include/Peripheral/UART/Reg
- SHAL/Include/Peripheral/ADC
- SHAL/Include/Peripheral/ADC/Reg
SHAL/Src
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
)
@@ -68,8 +62,6 @@ file(GLOB_RECURSE PROJECT_SOURCES
#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}/Peripheral/UART/*.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/ADC/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Core/*.cpp
)
diff --git a/MX/F030x6/STM32F030XX_FLASH.ld b/MX/F030x6/STM32F030XX_FLASH.ld
new file mode 100644
index 0000000..880a69d
--- /dev/null
+++ b/MX/F030x6/STM32F030XX_FLASH.ld
@@ -0,0 +1,249 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : STM32CubeMX
+**
+** Abstract : Linker script for STM32F030K6Tx series
+** 32Kbytes FLASH and 4Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+**
© COPYRIGHT(c) 2025 STMicroelectronics
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of STMicroelectronics nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K
+}
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ {
+ . = ALIGN(4);
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ {
+ . = ALIGN(4);
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ . = ALIGN(4);
+ } >FLASH
+
+ .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ {
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ . = ALIGN(4);
+ } >FLASH
+
+ .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ {
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ . = ALIGN(4);
+ } >FLASH
+
+ .fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+ {
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ . = ALIGN(4);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+ *(.RamFunc) /* .RamFunc sections */
+ *(.RamFunc*) /* .RamFunc* sections */
+
+ . = ALIGN(4);
+ } >RAM AT> FLASH
+
+ /* Initialized TLS data section */
+ .tdata : ALIGN(4)
+ {
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ PROVIDE(__data_end = .);
+ PROVIDE(__tdata_end = .);
+ } >RAM AT> FLASH
+
+ PROVIDE( __tdata_start = ADDR(.tdata) );
+ PROVIDE( __tdata_size = __tdata_end - __tdata_start );
+
+ PROVIDE( __data_start = ADDR(.data) );
+ PROVIDE( __data_size = __data_end - __data_start );
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
+ PROVIDE( __tdata_source_size = __tdata_source_end - __tdata_source );
+
+ PROVIDE( __data_source = LOADADDR(.data) );
+ PROVIDE( __data_source_end = __tdata_source_end );
+ PROVIDE( __data_source_size = __data_source_end - __data_source );
+ /* Uninitialized data section */
+ .tbss (NOLOAD) : ALIGN(4)
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.tbss .tbss.*)
+ . = ALIGN(4);
+ PROVIDE( __tbss_end = . );
+ } >RAM
+
+ PROVIDE( __tbss_start = ADDR(.tbss) );
+ PROVIDE( __tbss_size = __tbss_end - __tbss_start );
+ PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
+
+ PROVIDE( __tls_base = __tdata_start );
+ PROVIDE( __tls_end = __tbss_end );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+ PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
+ PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1) );
+ PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
+ PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
+
+ .bss (NOLOAD) : ALIGN(4)
+ {
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ PROVIDE( __bss_end = .);
+ } >RAM
+ PROVIDE( __non_tls_bss_start = ADDR(.bss) );
+
+ PROVIDE( __bss_start = __tbss_start );
+ PROVIDE( __bss_size = __bss_end - __bss_start );
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack (NOLOAD) :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a:* ( * )
+ libm.a:* ( * )
+ libgcc.a:* ( * )
+ }
+
+}
diff --git a/MX/F030x6/startup_stm32f030x6.s b/MX/F030x6/startup_stm32f030x6.s
new file mode 100644
index 0000000..9f89ad9
--- /dev/null
+++ b/MX/F030x6/startup_stm32f030x6.s
@@ -0,0 +1,258 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f030x6.s
+ * @author MCD Application Team
+ * @brief STM32F030x4/STM32F030x6 devices vector table for GCC toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M0 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m0
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr r0, =_estack
+ mov sp, r0 /* set stack pointer */
+
+/* Call the clock system initialization function.*/
+ bl SystemInit
+
+/* Copy the data segment initializers from flash to SRAM */
+ ldr r0, =_sdata
+ ldr r1, =_edata
+ ldr r2, =_sidata
+ movs r3, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r4, [r2, r3]
+ str r4, [r0, r3]
+ adds r3, r3, #4
+
+LoopCopyDataInit:
+ adds r4, r0, r3
+ cmp r4, r1
+ bcc CopyDataInit
+
+/* Zero fill the bss segment. */
+ ldr r2, =_sbss
+ ldr r4, =_ebss
+ movs r3, #0
+ b LoopFillZerobss
+
+FillZerobss:
+ str r3, [r2]
+ adds r2, r2, #4
+
+LoopFillZerobss:
+ cmp r2, r4
+ bcc FillZerobss
+
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+
+LoopForever:
+ b LoopForever
+
+
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M0. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word 0
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word 0 /* Reserved */
+ .word RTC_IRQHandler /* RTC through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
+ .word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
+ .word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
+ .word 0 /* Reserved */
+ .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
+ .word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
+ .word DMA1_Channel4_5_IRQHandler /* DMA1 Channel 4 and Channel 5 */
+ .word ADC1_IRQHandler /* ADC1 */
+ .word TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word 0 /* Reserved */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word TIM14_IRQHandler /* TIM14 */
+ .word 0 /* Reserved */
+ .word TIM16_IRQHandler /* TIM16 */
+ .word TIM17_IRQHandler /* TIM17 */
+ .word I2C1_IRQHandler /* I2C1 */
+ .word 0 /* Reserved */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word 0 /* Reserved */
+ .word USART1_IRQHandler /* USART1 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_1_IRQHandler
+ .thumb_set EXTI0_1_IRQHandler,Default_Handler
+
+ .weak EXTI2_3_IRQHandler
+ .thumb_set EXTI2_3_IRQHandler,Default_Handler
+
+ .weak EXTI4_15_IRQHandler
+ .thumb_set EXTI4_15_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_3_IRQHandler
+ .thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_5_IRQHandler
+ .thumb_set DMA1_Channel4_5_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_UP_TRG_COM_IRQHandler
+ .thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM14_IRQHandler
+ .thumb_set TIM14_IRQHandler,Default_Handler
+
+ .weak TIM16_IRQHandler
+ .thumb_set TIM16_IRQHandler,Default_Handler
+
+ .weak TIM17_IRQHandler
+ .thumb_set TIM17_IRQHandler,Default_Handler
+
+ .weak I2C1_IRQHandler
+ .thumb_set I2C1_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+
+
diff --git a/Makefile b/Makefile
index 9eb2ab5..9328010 100644
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,8 @@ BUILD_TYPE ?= Debug
TOOLCHAIN := gcc-arm-none-eabi.cmake
# MCU target (override on command line: make build MCU_MODEL=STM32F051x8)
-MCU_MODEL ?= STM32H753xx
-MCU_FAMILY ?= STM32H7xx
+MCU_MODEL ?= STM32F072xB
+MCU_FAMILY ?= STM32F0xx
# --- Default target ---
all: build
diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h
index 398383d..1c34664 100644
--- a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h
+++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h
@@ -52,8 +52,10 @@ public:
//Capture Compare Functions
void setCaptureCompareValue(SHAL_Timer_Channel channel, uint32_t value) const;
+
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);
+
+ void setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode) const;
//Set TIMER_KEY IRQ callback function
void setCallbackFunc(TimerCallback callback) const {
diff --git a/SHAL/Include/SHAL.h b/SHAL/Include/SHAL.h
index 751b34d..ca58a11 100644
--- a/SHAL/Include/SHAL.h
+++ b/SHAL/Include/SHAL.h
@@ -10,9 +10,6 @@
#include "SHAL_TIM.h"
#include "SHAL_GPIO.h"
-#include "SHAL_UART.h"
-#include "SHAL_ADC.h"
-
#endif
diff --git a/SHAL/Src/STM32F0xx/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32F0xx/Peripheral/GPIO/SHAL_GPIO.cpp
index 239114d..7ac6dec 100644
--- a/SHAL/Src/STM32F0xx/Peripheral/GPIO/SHAL_GPIO.cpp
+++ b/SHAL/Src/STM32F0xx/Peripheral/GPIO/SHAL_GPIO.cpp
@@ -18,42 +18,42 @@ SHAL_GPIO::SHAL_GPIO(GPIO_Key key) : m_GPIO_KEY(key) {
SHAL_set_register_value(GPIORCCEnable.reg,GPIORCCEnable.mask);
}
-void SHAL_GPIO::setLow() {
+void SHAL_GPIO::setLow() const {
auto outputDataReg = getGPIOOutputDataRegister(m_GPIO_KEY);
SHAL_set_bits(outputDataReg.reg,1,0,outputDataReg.offset);
}
-void SHAL_GPIO::setHigh() {
+void SHAL_GPIO::setHigh() const {
auto outputDataReg = getGPIOOutputDataRegister(m_GPIO_KEY);
SHAL_set_bits(outputDataReg.reg,1,1,outputDataReg.offset);
}
-void SHAL_GPIO::toggle() volatile {
+void SHAL_GPIO::toggle() const volatile {
auto outputDataReg = getGPIOOutputDataRegister(m_GPIO_KEY);
SHAL_flip_bits(outputDataReg.reg,1,outputDataReg.offset);
}
-void SHAL_GPIO::setOutputType(PinType type) volatile {
+void SHAL_GPIO::setOutputType(PinType type) const volatile {
auto outputTypeReg = getGPIOOutputTypeRegister(m_GPIO_KEY);
SHAL_set_bits(outputTypeReg.reg,2,static_cast(type),outputTypeReg.offset);
}
-void SHAL_GPIO::setOutputSpeed(OutputSpeed speed) volatile {
+void SHAL_GPIO::setOutputSpeed(OutputSpeed speed) const volatile {
auto outputSpeedReg = getGPIOOutputSpeedRegister(m_GPIO_KEY);
SHAL_set_bits(outputSpeedReg.reg,2,static_cast(speed),outputSpeedReg.offset);
}
-void SHAL_GPIO::setInternalResistor(InternalResistorType type) volatile {
+void SHAL_GPIO::setInternalResistor(InternalResistorType type) const volatile {
auto pupdreg = getGPIOPUPDRegister(m_GPIO_KEY);
SHAL_set_bits(pupdreg.reg,2,static_cast(type),pupdreg.offset);
}
-void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function AF) volatile {
+void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function AF) const volatile {
auto alternateFunctionReg = getGPIOAlternateFunctionRegister(m_GPIO_KEY);
SHAL_set_bits(alternateFunctionReg.reg,4,static_cast(AF),alternateFunctionReg.offset);
}
-SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) volatile {
+SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) const volatile {
auto pinModeReg = getGPIOModeRegister(m_GPIO_KEY);
/*
diff --git a/SHAL/Src/STM32F0xx/Peripheral/Timer/SHAL_TIM.cpp b/SHAL/Src/STM32F0xx/Peripheral/Timer/SHAL_TIM.cpp
index 618ac48..c8b52f2 100644
--- a/SHAL/Src/STM32F0xx/Peripheral/Timer/SHAL_TIM.cpp
+++ b/SHAL/Src/STM32F0xx/Peripheral/Timer/SHAL_TIM.cpp
@@ -34,19 +34,19 @@ void Timer::start() {
enableInterrupt();
}
-void Timer::stop() {
+void Timer::stop() const {
auto rcc_reg = getTimerRCC(m_key);
SHAL_clear_bitmask(rcc_reg.reg,rcc_reg.enable_mask);
}
-void Timer::setPrescaler(const uint16_t presc) const {
+void Timer::setPrescaler(const uint32_t presc) const {
auto prescalerReg = getTimerPrescalerRegister(m_key);
SHAL_set_bits(prescalerReg.reg,16,presc,0);
}
-void Timer::setARR(const uint16_t arr) const {
+void Timer::setARR(const uint32_t arr) const {
auto autoReloadReg = getTimerAutoReloadRegister(m_key);
SHAL_set_bits(autoReloadReg.reg,16,arr,0);}
@@ -56,7 +56,7 @@ void Timer::enableInterrupt() {
NVIC_EnableIRQ(getIRQn(m_key));
}
-void Timer::init(uint16_t prescaler, uint16_t autoReload) {
+void Timer::init(uint32_t prescaler, uint32_t autoReload) {
SHAL_TIM_RCC_Register rcc = getTimerRCC(m_key);
SHAL_apply_bitmask(rcc.reg,rcc.enable_mask);
@@ -65,7 +65,7 @@ void Timer::init(uint16_t prescaler, uint16_t autoReload) {
setARR(autoReload);
}
-void Timer::configurePWM(SHAL_Timer_Channel channel, uint16_t prescaler, uint16_t autoReload, uint16_t captureCompareThreshold) {
+void Timer::configurePWM(SHAL_Timer_Channel channel, uint32_t prescaler, uint32_t autoReload, uint32_t captureCompareThreshold) {
setPrescaler(prescaler);
setARR(autoReload);
@@ -76,7 +76,7 @@ void Timer::configurePWM(SHAL_Timer_Channel channel, uint16_t prescaler, uint16_
setCaptureCompareValue(channel, captureCompareThreshold);
}
-void Timer::configureOneshot(SHAL_Timer_Channel channel, uint16_t prescaler, uint16_t autoReload, uint16_t captureCompareThreshold) {
+void Timer::configureOneshot(SHAL_Timer_Channel channel, uint32_t prescaler, uint32_t autoReload, uint32_t captureCompareThreshold) {
setPrescaler(prescaler);
setARR(autoReload);
@@ -87,7 +87,7 @@ void Timer::configureOneshot(SHAL_Timer_Channel channel, uint16_t prescaler, uin
setCaptureCompareValue(channel, captureCompareThreshold);
}
-void Timer::setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode) {
+void Timer::setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode) const {
auto channelNum = static_cast(channel);
@@ -114,7 +114,7 @@ void Timer::enableChannel(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Ou
SHAL_set_bits(captureCompareEnableReg.reg,16,setValue,0);
}
-void Timer::setCaptureCompareValue(SHAL_Timer_Channel channel, uint16_t value) {
+void Timer::setCaptureCompareValue(SHAL_Timer_Channel channel, uint32_t value) const {
auto captureCompareReg = getTimerCaptureCompareRegister(m_key,channel);
SHAL_set_bits(captureCompareReg.reg,16,value,0);
diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp
index 8b98e63..8168223 100644
--- a/SHAL/Src/main.cpp
+++ b/SHAL/Src/main.cpp
@@ -1,274 +1,20 @@
#include "SHAL.h"
-#include
-#include
-#include
-
-
-char UARTRxBytes[60];
-int curr_uart_char = 0;
-
-void UARTCommandHandler(const char* string);
-
-extern "C" void USART3_IRQHandler(void)
-{
- // Check RXNE flag (receive register not empty)
-
- if (USART3->ISR & USART_ISR_RXNE_RXFNE)
- {
- auto byte = static_cast((USART3->RDR & 0xFF));
-
-
- if (byte == '\r' || byte == '\n'){ //Enter case
- SHAL_UART3.sendString("\r\n");
-
- UARTCommandHandler(UARTRxBytes);
-
- for (char & UARTRxByte : UARTRxBytes) { //Clear array
- UARTRxByte = 0;
- }
- curr_uart_char = 0;
- }
-
- else if (byte == 0x7F || byte == 0x08){ //Backspace case
- if (curr_uart_char > 0) {
- UARTRxBytes[--curr_uart_char] = 0;
- SHAL_UART3.sendChar(0x08); //Move cursor back
- SHAL_UART3.sendChar(' '); //Send space
- SHAL_UART3.sendChar(0x08); //Move cursor back
- }
- }
-
-
- else {
- SHAL_UART3.sendChar(byte);
- UARTRxBytes[curr_uart_char] = byte;
- curr_uart_char++;
- }
- }
-}
-
-struct timerInfo {
- const char* name{};
- Timer timer;
-};
-
-struct gpioTimerMap {
- GPIO_Key key;
- const char* timerName;
- SHAL_Timer_Channel channel;
- GPIO_Alternate_Function af;
-};
-
-struct adcMap {
- GPIO_Key key;
- SHAL_ADC_Channel channel;
-};
-
-constexpr int NUM_TIMERS = 14;
-
-const timerInfo timers[NUM_TIMERS] = {
- {"TIM1", SHAL_TIM1},
- {"TIM2", SHAL_TIM2},
- {"TIM3", SHAL_TIM3},
- {"TIM4", SHAL_TIM4},
- {"TIM5", SHAL_TIM5},
- {"TIM6", SHAL_TIM6},
- {"TIM7", SHAL_TIM7},
- {"TIM8", SHAL_TIM8},
- {"TIM12", SHAL_TIM12},
- {"TIM13", SHAL_TIM13},
- {"TIM14", SHAL_TIM14},
- {"TIM15", SHAL_TIM15},
- {"TIM16", SHAL_TIM16},
- {"TIM17", SHAL_TIM17},
-};
-
-#include "User_Config.h"
-
-void UARTCommandHandler(const char* string)
-{
- char words[10][12]; //10 words max, 6 chars + null terminator
- int curr_word = 0;
- int curr_char = 0;
-
- for (size_t i = 0; i < 60 && curr_word < 10; i++)
- {
- char c = string[i];
-
- if (c == ' ' || c == '\0')
- {
- if (curr_char > 0) // Ignore multiple spaces
- {
- words[curr_word][curr_char] = '\0'; // Null terminate
- curr_word++;
- curr_char = 0; // Reset for next word
- }
-
- if (c == '\0') break; //End of string
- }
- else if (curr_char < 11)
- {
- words[curr_word][curr_char++] = c;
- }
- }
-
- if (words[0][0] == 'P') { //Pin starts with P
- //Check for valid pin
- const uint8_t portNum = static_cast(words[0][1]) - 'A'; //Port number
- const auto pinNum = atoi((words[0] + 2)); //Pin number
-
- if ((portNum < AVAILABLE_PORTS - 1) && (pinNum < PINS_PER_PORT)) { //Valid pin
-
- auto pin = GPIOManager::get(portNum,pinNum); //Get GPIO pin
-
- if (strcmp(words[1], "SET") == 0) { //SET ------------------------------------------
-
- if (curr_word < 3) return; //No subcommand, seg fault
-
- pin.setPinMode(PinMode::OUTPUT_MODE);
-
- if (strcmp(words[2], "HIGH") == 0) { //GPIO toggle
- pin.setHigh();
- }
- else if (strcmp(words[2], "LOW") == 0) {
- pin.setLow();
- }
- }
- else if (strcmp(words[1], "TOG") == 0) { //TOGGLE ------------------------------------------
- pin.setPinMode(PinMode::OUTPUT_MODE);
- pin.toggle();
- }
- else if (strcmp(words[1], "READ") == 0) { //TOGGLE ------------------------------------------
- pin.setPinMode(PinMode::INPUT_MODE);
-
- SHAL_delay_us(10);
-
- const uint16_t val = pin.digitalRead();
- char buff[8];
- snprintf(buff, 8, "%d\r\n", val);
- SHAL_UART3.sendString(buff);
- }
- else if (strcmp(words[1], "ADC") == 0) { //ADC READ -------------------------------------------
- pin.setPinMode(PinMode::ANALOG_MODE);
-
- SHAL_ADC_Channel channel;
- bool found = false;
-
- for (adcMap map : adcInfo) {
- if (pin.getKey() == map.key) {
- channel = map.channel;
- found = true;
- }
- }
-
- if (!found) {
- SHAL_UART3.sendString("INVALID ADC\r\n");
- return;
- }
-
- const auto res = SHAL_ADC1.singleConvertSingle(channel, SHAL_ADC_SampleTime::C8);
-
- char buff[32];
- uint32_t millivolts = ((uint32_t)res * 3300) / 65535;
- snprintf(buff, sizeof(buff), "%lu.%03lu V\r\n", millivolts / 1000, millivolts % 1000);
- SHAL_UART3.sendString(buff);
- }
- }else {
- SHAL_UART3.sendString("INVALID PIN");
- }
- }
- else if (strncmp(words[0],"TIM",3) == 0) { //Timer control ---------------------------------------------
- const char* timNumStr = words[0];
- int timerNum = 0;
- bool validTimer = false;
-
- for (int i = 0; i < NUM_TIMERS; i++) { //Num timers
- if (strcmp(timers[i].name,timNumStr) == 0) {
- validTimer = true;
- timerNum = i;
- break;
- }
- }
-
- if (!validTimer) {
- SHAL_UART3.sendString("INVALID TIMER\r\n");
- return;
- }
-
- Timer currTimer = timers[timerNum].timer; //get our timer
-
- if (strcmp(words[1], "START") == 0) { //SET ------------------------------------------
- currTimer.init();
-
- currTimer.start();
-
- SHAL_UART3.sendString("Started timer\r\n");
- }
- else if (strcmp(words[1], "STOP") == 0) {
- currTimer.stop();
- SHAL_UART3.sendString("Stopped timer\r\n");
-
- }
- else if (strncmp(words[1], "CH",2) == 0) { //Channel selection
-
- int channelNum = atoi((words[1] + 2));
- auto timerChannel = static_cast(channelNum);
-
- if (strcmp(words[2], "PWM") == 0) {
- currTimer.stop();
-
- for (int i = 0; i < NUM_TIMER_GPIOS; i++) {
- if (strcmp(gpioTimerInfo[i].timerName,words[0]) == 0) {
- if (gpioTimerInfo[i].channel == timerChannel) {
-
- auto gpio_key = gpioTimerInfo[i].key;
- auto gpio = GPIOManager::get(gpio_key);
-
- gpio.setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
- gpio.setAlternateFunction(gpioTimerInfo[i].af);
-
- break;
-
- }
- }
- }
-
- const uint32_t psc = atoi(words[3]);
- const uint32_t arr = atoi(words[4]);
- const uint32_t cc = atoi(words[5]);
-
- currTimer.init();
-
- currTimer.configurePWM(timerChannel,psc,arr,cc);
-
- currTimer.start();
- }
- }
- else {
- SHAL_UART3.sendString("BAD TIM COMMAND\r\n");
- return;
- }
- }
-}
-
int main() {
SHAL_init();
- NVIC_SetPriority(USART3_IRQn, 1); //Enable UART interrupts
- NVIC_EnableIRQ(USART3_IRQn);
+ PIN(A15).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
- SHAL_UART3.init(UART_Pair_Key::Tx3D8_Rx3D9);
- SHAL_UART3.begin(115200,SHAL_USART_Word_Length::Bits_8);
+ PIN(A15).setAlternateFunction(GPIO_Alternate_Function::AF2);
- SHAL_ADC1.init(ADC_Key::S_ADC1, SHAL_ADC_Sample_Mode::SINGLE_ENDED);
+ SHAL_TIM1.configurePWM(SHAL_Timer_Channel::CH4, 1, 800, 10);
- for (const adcMap map : adcInfo) {
- SHAL_ADC1.preselectChannel(map.channel);
- }
+ SHAL_TIM1.start();
while (true) {
+
+ SHAL_delay_ms(2000);
}
}
\ No newline at end of file