From 5abb41a777611d68a8ea6af5cbab755a9077d71c Mon Sep 17 00:00:00 2001 From: Xander B Date: Mon, 3 Feb 2025 20:18:43 -0500 Subject: [PATCH 01/22] copied my pwm input code from the older branch --- samples/CMakeLists.txt | 1 + samples/pwm_input/CMakeLists.txt | 3 + samples/pwm_input/main.cpp | 216 +++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 samples/pwm_input/CMakeLists.txt create mode 100644 samples/pwm_input/main.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 2949ab70..883aa1a7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(lcd) add_subdirectory(log) add_subdirectory(millis) add_subdirectory(pwm) +add_subdirectory(pwm_input) add_subdirectory(queue) add_subdirectory(read_write) add_subdirectory(rtc) diff --git a/samples/pwm_input/CMakeLists.txt b/samples/pwm_input/CMakeLists.txt new file mode 100644 index 00000000..93179064 --- /dev/null +++ b/samples/pwm_input/CMakeLists.txt @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/evt-core_build.cmake) + +make_exe(pwm_input main.cpp) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp new file mode 100644 index 00000000..f42fe784 --- /dev/null +++ b/samples/pwm_input/main.cpp @@ -0,0 +1,216 @@ +// +// Created by dylan on 2/3/2025. +// + + +#include +#include +#include +#include +#include + +/* Private defines -----------------------------------------------------------*/ +#define B1_Pin GPIO_PIN_13 +#define B1_GPIO_Port GPIOC +#define USART_TX_Pin GPIO_PIN_2 +#define USART_TX_GPIO_Port GPIOA +#define USART_RX_Pin GPIO_PIN_3 +#define USART_RX_GPIO_Port GPIOA +#define LD2_Pin GPIO_PIN_13 +#define LD2_GPIO_Port GPIOB +#define TMS_Pin GPIO_PIN_13 +#define TMS_GPIO_Port GPIOA +#define TCK_Pin GPIO_PIN_14 +#define TCK_GPIO_Port GPIOA +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB + +namespace io = core::io; +namespace time = core::time; +namespace log = core::log; + +TIM_HandleTypeDef htim2; + +static void MX_GPIO_Init(void); +static void MX_TIM2_Init(void); + +void Error_Handler(void); + +// IRQ handler for TIM2 +void TIM2_IRQHandler(void) { + HAL_TIM_IRQHandler(&htim2); +} + +uint32_t ICValue = 0; +uint32_t Frequency = 0; +uint32_t Duty = 0; + +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { + log::LOGGER.log(log::Logger::LogLevel::DEBUG, "CAPTURE_CALLBACK!!"); + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // If the interrupt is triggered by channel 1 + { + // Read the IC value + ICValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); + + if (ICValue != 0) // first value is zero, non zero is period + { + // calculate the Duty Cycle + // signal high time/ period = duty cycle + Duty = (HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) * 100) / ICValue; + + Frequency = SystemCoreClock / ICValue; // APB1 Timer clocks/period = F + } + } +} + +int main(void) { + // Initialize system + core::platform::init(); + // Setup UART + io::UART& uart = io::getUART(9600); + + // setup logger + log::LOGGER.setUART(&uart); + log::LOGGER.setLogLevel(log::Logger::LogLevel::DEBUG); + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_TIM2_Init(); + + uart.printf("START INPUT CAPTURE\n\r"); + // input capture + // enable TIM2 interrupt, set priority + HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); + // enable interrupt src + HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // main channel + HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_2); // indirect channel + + uart.printf("END INPUT CAPTURE\n\r"); + while (1) { + time::wait(1000); + uart.printf("\n\rICValue: %d\n\r", ICValue); + uart.printf("\n\rFrequency: %d\n\r", Frequency); + uart.printf("\n\rDuty: %d\n\r", Duty); + uart.printf("\n\r----------------------------------\n\r"); + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ + +static void MX_TIM2_Init(void) { + /* USER CODE BEGIN TIM2_Init 0 */ + log::LOGGER.log(log::Logger::LogLevel::DEBUG, "TIM2_INIT"); + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_SlaveConfigTypeDef sSlaveConfig = {0}; + TIM_IC_InitTypeDef sConfigIC = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 4294967295; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { + Error_Handler(); + } + if (HAL_TIM_IC_Init(&htim2) != HAL_OK) { + Error_Handler(); + } + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; + sSlaveConfig.TriggerFilter = 0; + if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK) { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + sConfigIC.ICFilter = 0; + if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_RCC_TIM2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + /* USER CODE END TIM2_Init 2 */ +} + +static void MX_GPIO_Init(void) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + log::LOGGER.log(log::Logger::LogLevel::DEBUG, "GPIO_INIT"); + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin : B1_Pin */ + GPIO_InitStruct.Pin = B1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LD2_Pin */ + GPIO_InitStruct.Pin = LD2_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + /* USER CODE END MX_GPIO_Init_2 */ +} + +void Error_Handler(void) { + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + // TODO Report Hal error return state + log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Bad"); + } + /* USER CODE END Error_Handler_Debug */ +} \ No newline at end of file From b0280cd9a7c7c4a6827d57758f6c72218c605384 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 6 Feb 2025 19:46:02 -0500 Subject: [PATCH 02/22] pwm_input works --- samples/pwm_input/main.cpp | 60 ++------------------------- samples/rtos/threadx-demo/main.cpp | 10 ++--- src/core/dev/LCD.cpp | 10 ++--- src/core/io/platform/f3xx/ADCf3xx.cpp | 2 +- src/core/io/platform/f4xx/ADCf4xx.cpp | 2 +- src/core/rtos/tsio/ThreadUART.cpp | 2 +- 6 files changed, 17 insertions(+), 69 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index f42fe784..588e3992 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -1,7 +1,5 @@ -// -// Created by dylan on 2/3/2025. -// +// Xander 2/3/2025. #include #include @@ -9,22 +7,6 @@ #include #include -/* Private defines -----------------------------------------------------------*/ -#define B1_Pin GPIO_PIN_13 -#define B1_GPIO_Port GPIOC -#define USART_TX_Pin GPIO_PIN_2 -#define USART_TX_GPIO_Port GPIOA -#define USART_RX_Pin GPIO_PIN_3 -#define USART_RX_GPIO_Port GPIOA -#define LD2_Pin GPIO_PIN_13 -#define LD2_GPIO_Port GPIOB -#define TMS_Pin GPIO_PIN_13 -#define TMS_GPIO_Port GPIOA -#define TCK_Pin GPIO_PIN_14 -#define TCK_GPIO_Port GPIOA -#define SWO_Pin GPIO_PIN_3 -#define SWO_GPIO_Port GPIOB - namespace io = core::io; namespace time = core::time; namespace log = core::log; @@ -37,7 +19,7 @@ static void MX_TIM2_Init(void); void Error_Handler(void); // IRQ handler for TIM2 -void TIM2_IRQHandler(void) { +extern "C" void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); } @@ -74,7 +56,6 @@ int main(void) { log::LOGGER.setLogLevel(log::Logger::LogLevel::DEBUG); /* Initialize all configured peripherals */ - MX_GPIO_Init(); MX_TIM2_Init(); uart.printf("START INPUT CAPTURE\n\r"); @@ -112,7 +93,7 @@ static void MX_TIM2_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ - + __HAL_RCC_TIM2_CLK_ENABLE(); /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 0; @@ -157,7 +138,6 @@ static void MX_TIM2_Init(void) { } /* USER CODE BEGIN TIM2_Init 2 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; - __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**TIM2 GPIO Configuration @@ -172,38 +152,6 @@ static void MX_TIM2_Init(void) { /* USER CODE END TIM2_Init 2 */ } -static void MX_GPIO_Init(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - /* USER CODE BEGIN MX_GPIO_Init_1 */ - log::LOGGER.log(log::Logger::LogLevel::DEBUG, "GPIO_INIT"); - /* USER CODE END MX_GPIO_Init_1 */ - - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOF_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); - - /*Configure GPIO pin : B1_Pin */ - GPIO_InitStruct.Pin = B1_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pin : LD2_Pin */ - GPIO_InitStruct.Pin = LD2_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); - - /* USER CODE BEGIN MX_GPIO_Init_2 */ - /* USER CODE END MX_GPIO_Init_2 */ -} - void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ @@ -213,4 +161,4 @@ void Error_Handler(void) { log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Bad"); } /* USER CODE END Error_Handler_Debug */ -} \ No newline at end of file +} diff --git a/samples/rtos/threadx-demo/main.cpp b/samples/rtos/threadx-demo/main.cpp index 3b58f8dc..67747ae4 100644 --- a/samples/rtos/threadx-demo/main.cpp +++ b/samples/rtos/threadx-demo/main.cpp @@ -52,7 +52,7 @@ typedef struct counters { * Struct that holds the arguments for the thread that generates the numbers */ struct numberGenThreadArgs { - rtos::Queue* outputQueue; // The queue of numbers that the number gen thread add it's generated number to + rtos::Queue* outputQueue; // The queue of numbers that the number gen thread add it's generated number to rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or printing // to uart at the same time these shouldn't necessarily need to be mutually exclusive, @@ -68,17 +68,17 @@ struct numberGenThreadArgs { * Struct that holds the arguments for all other threads */ struct numberConsumerThreadArgs { - rtos::Queue* inputQueue; // The queue that the threads will pull values that the number gen thread adds + rtos::Queue* inputQueue; // The queue that the threads will pull values that the number gen thread adds - rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or - // printing to uart + rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or + // printing to uart rtos::tsio::ThreadUART* threadUART; // The instance of ThreadUART that this thread will use to print. rtos::EventFlags* eventFlags; // the EventFlags that the number consumer threads will use to show they have gotten a // number, which will trigger the eventFlagThread to run it's own method. - uint8_t num; // What number this thread is + uint8_t num; // What number this thread is counters_t* counters; // the struct of counters for the number consumer threads to increase their counters when they // get a number diff --git a/src/core/dev/LCD.cpp b/src/core/dev/LCD.cpp index 41c78cef..adfb86b2 100644 --- a/src/core/dev/LCD.cpp +++ b/src/core/dev/LCD.cpp @@ -78,7 +78,7 @@ void LCD::driveColumn(uint8_t page, uint8_t colUp, uint8_t colLow, uint8_t data) } void LCD::clearLCD() { - uint8_t page = 0xB0; // The starting page + uint8_t page = 0xB0; // The starting page this->commandWrite(0x40); // Display start address + 0x40 for (uint8_t i = 0; i < 8; i++) { // 64 pixel display / 8 pixels per page = 8 pages @@ -88,7 +88,7 @@ void LCD::clearLCD() { for (uint8_t j = 0; j < screenSizeX; j++) { // 128 columns wide this->dataWrite(0x00); // Write clear pixels } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); } @@ -110,7 +110,7 @@ void LCD::clearArea(uint8_t width, uint8_t numPages, uint8_t page, uint8_t colum this->dataWrite(0x00); // Write Clear Pixels } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); // Finish Writing } @@ -126,7 +126,7 @@ void LCD::setEntireScreenBitMap(const uint8_t* bitMap) { this->dataWrite(*bitMap); // write pixels from bitmap bitMap++; // Advance the bitmap pointer by one. This means we can just grab the last one the next loop. } - page++; // after 128 columns, go to next page + page++; // after 128 columns, go to next page } this->commandWrite(0xAF); } @@ -149,7 +149,7 @@ void LCD::displayBitMapInArea(uint8_t* bitMap, uint8_t bitMapWidth, uint8_t numP bitMap++; // Advance the bitmap pointer by one. This means we can just grab the last one the next loop. } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); // Finish writing } diff --git a/src/core/io/platform/f3xx/ADCf3xx.cpp b/src/core/io/platform/f3xx/ADCf3xx.cpp index dbf8d8f4..a1286081 100644 --- a/src/core/io/platform/f3xx/ADCf3xx.cpp +++ b/src/core/io/platform/f3xx/ADCf3xx.cpp @@ -185,7 +185,7 @@ void ADCf3xx::addChannel(uint8_t rank) { default: channelStruct = {}; // sets all variables to 0 log::LOGGER.log(log::Logger::LogLevel::ERROR, "INVALID PIN 0x%x!!", pin); - break; // Should never get here + break; // Should never get here } // Subtract 1 because rank starts at 1 diff --git a/src/core/io/platform/f4xx/ADCf4xx.cpp b/src/core/io/platform/f4xx/ADCf4xx.cpp index fb86f589..30f3ebf4 100644 --- a/src/core/io/platform/f4xx/ADCf4xx.cpp +++ b/src/core/io/platform/f4xx/ADCf4xx.cpp @@ -269,7 +269,7 @@ void ADCf4xx::addChannel(uint8_t rank) { default: channelStruct = {}; // sets all values to 0 log::LOGGER.log(log::Logger::LogLevel::ERROR, "INVALID PIN 0x%x!!", pin); - break; // Should never get here + break; // Should never get here } // This checks if the pin being used supports the ADC being used diff --git a/src/core/rtos/tsio/ThreadUART.cpp b/src/core/rtos/tsio/ThreadUART.cpp index 58606f9d..d912b7de 100644 --- a/src/core/rtos/tsio/ThreadUART.cpp +++ b/src/core/rtos/tsio/ThreadUART.cpp @@ -70,7 +70,7 @@ void ThreadUART::printf(const char* format, ...) { va_list args; /* Access the variable argument list */ va_start(args, format); /* Tells the args variable to point to the format parameter first */ - char buffer[256]; /* Buffer array to hold the message */ + char buffer[256]; /* Buffer array to hold the message */ vsnprintf(buffer, sizeof(buffer), format, args); /* vsnprint formats the string and stores it in the buffer array */ buffer[255] = '\0'; From 2c9ca249fd10a4a96b487eb7fd2579ab9352c7c9 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 6 Feb 2025 20:35:21 -0500 Subject: [PATCH 03/22] Created necessary classes in order to seperate HAL stuff from main and allow for a general PWM_INPUT for f3 --- CMakeLists.txt | 2 ++ include/core/io/PWM_INPUT.hpp | 10 ++++++++++ include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 10 ++++++++++ src/core/io/PWM_INPUT.cpp | 5 +++++ src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 5 +++++ 5 files changed, 32 insertions(+) create mode 100644 include/core/io/PWM_INPUT.hpp create mode 100644 include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp create mode 100644 src/core/io/PWM_INPUT.cpp create mode 100644 src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 548f795e..852fb9d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ target_sources(${PROJECT_NAME} PRIVATE src/core/io/GPIO.cpp src/core/io/I2C.cpp src/core/io/PWM.cpp + src/core/io/PWM_INPUT.cpp src/core/io/UART.cpp src/core/io/SPI.cpp src/core/io/types/CANMessage.cpp @@ -57,6 +58,7 @@ if(COMPDEFS MATCHES "(.*)STM32F3xx(.*)") src/core/io/platform/f3xx/GPIOf3xx.cpp src/core/io/platform/f3xx/I2Cf3xx.cpp src/core/io/platform/f3xx/PWMf3xx.cpp + src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp src/core/io/platform/f3xx/UARTf3xx.cpp src/core/io/platform/f3xx/SPIf3xx.cpp src/core/dev/platform/f3xx/IWDGf3xx.cpp diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp new file mode 100644 index 00000000..72689eec --- /dev/null +++ b/include/core/io/PWM_INPUT.hpp @@ -0,0 +1,10 @@ +// +// Created by dylan on 2/6/2025. +// + +#ifndef EVT_PWM_INPUT_HPP +#define EVT_PWM_INPUT_HPP + +class PWM_INPUT {}; + +#endif // EVT_PWM_INPUT_HPP diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp new file mode 100644 index 00000000..877c3cf7 --- /dev/null +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -0,0 +1,10 @@ +// +// Created by dylan on 2/6/2025. +// + +#ifndef EVT_PWM_INPUTF3XX_HPP +#define EVT_PWM_INPUTF3XX_HPP + +class PWM_INPUTf3xx {}; + +#endif // EVT_PWM_INPUTF3XX_HPP diff --git a/src/core/io/PWM_INPUT.cpp b/src/core/io/PWM_INPUT.cpp new file mode 100644 index 00000000..6a971ebe --- /dev/null +++ b/src/core/io/PWM_INPUT.cpp @@ -0,0 +1,5 @@ +// +// Created by dylan on 2/6/2025. +// + +#include "../../../include/core/io/PWM_INPUT.hpp" diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp new file mode 100644 index 00000000..cebb8dc0 --- /dev/null +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -0,0 +1,5 @@ +// +// Created by dylan on 2/6/2025. +// + +#include "../../../../../include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp" From 156284b1d55c188ff8bce79af2059026b36fa19a Mon Sep 17 00:00:00 2001 From: Xander B Date: Mon, 10 Feb 2025 20:55:22 -0500 Subject: [PATCH 04/22] Completed setup for class, with the exeption of the PWM_INPUTf3xx.cpp, need to figure out the pins --- include/core/io/PWM_INPUT.hpp | 56 +++++++++++++++++-- .../core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 38 +++++++++++-- src/core/io/PWM_INPUT.cpp | 15 +++-- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 14 +++-- 4 files changed, 107 insertions(+), 16 deletions(-) diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp index 72689eec..f28fb765 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWM_INPUT.hpp @@ -1,10 +1,58 @@ -// -// Created by dylan on 2/6/2025. -// #ifndef EVT_PWM_INPUT_HPP #define EVT_PWM_INPUT_HPP -class PWM_INPUT {}; +#include + +namespace core::io { + +//Different pins are hardware specific +enum class Pin; + +class PWM_INPUT { + +public: + /** + * Setup the given pin for PWM usage. + * + * @param[in] pin The pin to setup for PWM + */ + PWM_INPUT(Pin pin); + + /** + * Get the current duty cycle. + * + * @return The duty cycle the PWM input is operating at. + */ + virtual uint32_t getDutyCycle() = 0; + + /** + * Get the current period. + * + * @return The period the PWM input is operating at in microseconds. + */ + virtual uint32_t getPeriod() = 0; + + /** + * Get the current period. + * + * @return The frequency the PWM input is operating at in Hz. + */ + virtual uint32_t getFrequency() = 0; + + +protected : + /// The pin PWM input is on + Pin pin; + /// The duty cycle of the PWM input + uint32_t dutyCycle; + /// The period of the PWM input + uint32_t period; + /// The frequency of the PWM input + uint32_t frequency; + +}; + +} // namespace core::io #endif // EVT_PWM_INPUT_HPP diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index 877c3cf7..c2f8aba1 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -1,10 +1,40 @@ -// -// Created by dylan on 2/6/2025. -// #ifndef EVT_PWM_INPUTF3XX_HPP #define EVT_PWM_INPUTF3XX_HPP -class PWM_INPUTf3xx {}; +#include + +#include +#include +#include + +namespace core::io { + +class PWM_INPUTf3xx : public PWM_INPUT { +public: + /** + * Setup the given pin for PWM usage. + * + * @param pin[in] The pin to setup for PWM + */ + PWM_INPUTf3xx(Pin pin); + + uint32_t getDutyCycle(); + + uint32_t getPeriod(); + + uint32_t getFrequency(); + + +private: + /// HAL timer representation + TIM_HandleTypeDef halTIM; + /// Channel identification + uint32_t halTIMChannelID; + /// HAL channel representation + TIM_OC_InitTypeDef halChannel; +}; + +} // namespace core::io #endif // EVT_PWM_INPUTF3XX_HPP diff --git a/src/core/io/PWM_INPUT.cpp b/src/core/io/PWM_INPUT.cpp index 6a971ebe..e6879c50 100644 --- a/src/core/io/PWM_INPUT.cpp +++ b/src/core/io/PWM_INPUT.cpp @@ -1,5 +1,12 @@ -// -// Created by dylan on 2/6/2025. -// +#include -#include "../../../include/core/io/PWM_INPUT.hpp" +namespace core::io { + +PWM_INPUT::PWM_INPUT(core::io::Pin pin) { + this->pin = pin; + this->dutyCycle = 0; + this->period = 0; + this->frequency = 0; +} + +} // namespace core::io diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index cebb8dc0..b9e96e54 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -1,5 +1,11 @@ -// -// Created by dylan on 2/6/2025. -// -#include "../../../../../include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp" +#include +#include + +namespace core::io { + + +} + + + From 5178c45b88512d6df1a1dd28391ef6af26cb7298 Mon Sep 17 00:00:00 2001 From: Xander B Date: Sat, 29 Mar 2025 12:55:32 -0400 Subject: [PATCH 05/22] Everything except this tim15 config works --- include/core/io/PWM_INPUT.hpp | 6 +- .../core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 1 - samples/pwm/main.cpp | 2 +- samples/pwm_input/main.cpp | 90 ++++++++++++------- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 8 +- 5 files changed, 60 insertions(+), 47 deletions(-) diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp index f28fb765..bf8e01a4 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWM_INPUT.hpp @@ -6,7 +6,7 @@ namespace core::io { -//Different pins are hardware specific +// Different pins are hardware specific enum class Pin; class PWM_INPUT { @@ -40,8 +40,7 @@ class PWM_INPUT { */ virtual uint32_t getFrequency() = 0; - -protected : +protected: /// The pin PWM input is on Pin pin; /// The duty cycle of the PWM input @@ -50,7 +49,6 @@ protected : uint32_t period; /// The frequency of the PWM input uint32_t frequency; - }; } // namespace core::io diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index c2f8aba1..3a48c86c 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -25,7 +25,6 @@ class PWM_INPUTf3xx : public PWM_INPUT { uint32_t getFrequency(); - private: /// HAL timer representation TIM_HandleTypeDef halTIM; diff --git a/samples/pwm/main.cpp b/samples/pwm/main.cpp index c3745e0d..6d326dd3 100644 --- a/samples/pwm/main.cpp +++ b/samples/pwm/main.cpp @@ -17,7 +17,7 @@ int main() { // 1000000 microseconds (1 second) period pwm.setPeriod(1000000); // 50 % duty cycle - pwm.setDutyCycle(50); + pwm.setDutyCycle(70); while (1) { time::wait(5000); diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 588e3992..b4e9e6e8 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -1,6 +1,5 @@ // Xander 2/3/2025. - #include #include #include @@ -11,7 +10,27 @@ namespace io = core::io; namespace time = core::time; namespace log = core::log; -TIM_HandleTypeDef htim2; +// Defines for testing --------------------------------------------------------------------------------- +//Channel defines----- +#define directChannel TIM_CHANNEL_2 // TIM_CHANNEL_1 +#define activeDirectChannel HAL_TIM_ACTIVE_CHANNEL_1 // HAL_TIM_ACTIVE_CHANNEL_1 +#define indirectChannel TIM_CHANNEL_2 // TIM_CHANNEL_2 +#define triggerSource TIM_TS_TI2FP2 // TIM_TS_TI1FP1 +#define gpioClkEnable __HAL_RCC_GPIOA_CLK_ENABLE(); //__HAL_RCC_GPIOA_CLK_ENABLE(); +#define thePin GPIO_PIN_3 // GPIO_PIN_0 +#define altFunc GPIO_AF9_TIM15 // GPIO_AF1_TIM2 +#define gpioType GPIOA // GPIOA +//Timer Defines----- +#define TIMNum TIM15 //TIM 2 +#define IRQHandler TIM1_BRK_TIM15_IRQHandler //TIM2_IRQHandler +#define htimNum htim15 //htim2 +#define IRQNum TIM1_BRK_TIM15_IRQn //TIM2_IRQn +#define clkEnable __HAL_RCC_TIM15_CLK_ENABLE(); //__HAL_RCC_TIM2_CLK_ENABLE(); +//------------------------------------------------------------------------------------------------------- + +TIM_HandleTypeDef htimNum; + + static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); @@ -19,8 +38,8 @@ static void MX_TIM2_Init(void); void Error_Handler(void); // IRQ handler for TIM2 -extern "C" void TIM2_IRQHandler(void) { - HAL_TIM_IRQHandler(&htim2); +extern "C" void IRQHandler (void) { + HAL_TIM_IRQHandler(&htimNum); } uint32_t ICValue = 0; @@ -29,16 +48,16 @@ uint32_t Duty = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { log::LOGGER.log(log::Logger::LogLevel::DEBUG, "CAPTURE_CALLBACK!!"); - if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // If the interrupt is triggered by channel 1 + if (htim->Channel == activeDirectChannel) // If the interrupt is triggered by channel 1 { // Read the IC value - ICValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); + ICValue = HAL_TIM_ReadCapturedValue(htim, directChannel); if (ICValue != 0) // first value is zero, non zero is period { // calculate the Duty Cycle // signal high time/ period = duty cycle - Duty = (HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) * 100) / ICValue; + Duty = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / ICValue; Frequency = SystemCoreClock / ICValue; // APB1 Timer clocks/period = F } @@ -61,17 +80,17 @@ int main(void) { uart.printf("START INPUT CAPTURE\n\r"); // input capture // enable TIM2 interrupt, set priority - HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM2_IRQn); + HAL_NVIC_SetPriority(IRQNum, 0, 0); + HAL_NVIC_EnableIRQ(IRQNum); // enable interrupt src - HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // main channel - HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_2); // indirect channel + HAL_TIM_IC_Start_IT(&htimNum, directChannel); // main channel + HAL_TIM_IC_Start(&htimNum, indirectChannel); // indirect channel uart.printf("END INPUT CAPTURE\n\r"); while (1) { time::wait(1000); uart.printf("\n\rICValue: %d\n\r", ICValue); - uart.printf("\n\rFrequency: %d\n\r", Frequency); + uart.printf("\n\rFrequency: %d\n\r", Frequency) ; uart.printf("\n\rDuty: %d\n\r", Duty); uart.printf("\n\r----------------------------------\n\r"); } @@ -93,62 +112,65 @@ static void MX_TIM2_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ - __HAL_RCC_TIM2_CLK_ENABLE(); + //__HAL_RCC_TIM2_CLK_ENABLE(); + clkEnable; /* USER CODE END TIM2_Init 1 */ - htim2.Instance = TIM2; - htim2.Init.Prescaler = 0; - htim2.Init.CounterMode = TIM_COUNTERMODE_UP; - htim2.Init.Period = 4294967295; - htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { + htimNum.Instance = TIMNum; + htimNum.Init.Prescaler = 0; + htimNum.Init.CounterMode = TIM_COUNTERMODE_UP; + htimNum.Init.Period = 4294967295; + htimNum.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htimNum.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htimNum) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { + if (HAL_TIM_ConfigClockSource(&htimNum, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } - if (HAL_TIM_IC_Init(&htim2) != HAL_OK) { + if (HAL_TIM_IC_Init(&htimNum) != HAL_OK) { Error_Handler(); } sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; - sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; + sSlaveConfig.InputTrigger = triggerSource; sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; sSlaveConfig.TriggerFilter = 0; - if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK) { + if (HAL_TIM_SlaveConfigSynchro(&htimNum, &sSlaveConfig) != HAL_OK) { Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; - if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { + if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, directChannel) != HAL_OK) { Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; - if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) { + if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, indirectChannel) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { + if (HAL_TIMEx_MasterConfigSynchronization(&htimNum, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**TIM2 GPIO Configuration - PA0 ------> TIM2_CH1 - */ - GPIO_InitStruct.Pin = GPIO_PIN_0; + //__HAL_RCC_GPIOA_CLK_ENABLE(); + gpioClkEnable + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + */ + + GPIO_InitStruct.Pin = thePin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + GPIO_InitStruct.Alternate = altFunc; + HAL_GPIO_Init(gpioType, &GPIO_InitStruct); /* USER CODE END TIM2_Init 2 */ } diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index b9e96e54..e19161cd 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -2,10 +2,4 @@ #include #include -namespace core::io { - - -} - - - +namespace core::io {} From 58f0c4fc1029e66a32a4c7c4612a3a6ac0253e4e Mon Sep 17 00:00:00 2001 From: Xander B Date: Mon, 21 Apr 2025 20:55:04 -0400 Subject: [PATCH 06/22] All timers that should work work. --- samples/pwm_input/main.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index b4e9e6e8..0f45840f 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -12,12 +12,12 @@ namespace log = core::log; // Defines for testing --------------------------------------------------------------------------------- //Channel defines----- -#define directChannel TIM_CHANNEL_2 // TIM_CHANNEL_1 +#define directChannel TIM_CHANNEL_1 // TIM_CHANNEL_1 #define activeDirectChannel HAL_TIM_ACTIVE_CHANNEL_1 // HAL_TIM_ACTIVE_CHANNEL_1 -#define indirectChannel TIM_CHANNEL_2 // TIM_CHANNEL_2 -#define triggerSource TIM_TS_TI2FP2 // TIM_TS_TI1FP1 +#define indirectChannel TIM_CHANNEL_2 // TIM_CHANNEL_2 +#define triggerSource TIM_TS_TI1FP1 // TIM_TS_TI1FP1 #define gpioClkEnable __HAL_RCC_GPIOA_CLK_ENABLE(); //__HAL_RCC_GPIOA_CLK_ENABLE(); -#define thePin GPIO_PIN_3 // GPIO_PIN_0 +#define thePin GPIO_PIN_2 // GPIO_PIN_0 #define altFunc GPIO_AF9_TIM15 // GPIO_AF1_TIM2 #define gpioType GPIOA // GPIOA //Timer Defines----- @@ -28,6 +28,8 @@ namespace log = core::log; #define clkEnable __HAL_RCC_TIM15_CLK_ENABLE(); //__HAL_RCC_TIM2_CLK_ENABLE(); //------------------------------------------------------------------------------------------------------- + + TIM_HandleTypeDef htimNum; @@ -143,7 +145,7 @@ static void MX_TIM2_Init(void) { sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; - if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, directChannel) != HAL_OK) { + if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, directChannel) != HAL_OK) { //direct Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; From 1adeb76f342073f38c3f6d7e699730f5c74406af Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 28 Aug 2025 19:28:51 -0400 Subject: [PATCH 07/22] committing pre fall changes --- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 100 +++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index e19161cd..c995eff8 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -2,4 +2,102 @@ #include #include -namespace core::io {} +namespace core::io { + + + + + +PWM_INPUTf3xx::PWM_INPUTf3xx(core::io::Pin pin) { + TIM_TypeDef* instance; + uint32_t alternateFunction; + //getInstance(pin, &instance, &halTIMChannelID, &alternateFunction); + + if (instance == TIM1) { + __HAL_RCC_TIM1_CLK_ENABLE(); + } else if (instance == TIM2) { + __HAL_RCC_TIM2_CLK_ENABLE(); + } else if (instance == TIM15) { + __HAL_RCC_TIM15_CLK_ENABLE(); + } + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_SlaveConfigTypeDef sSlaveConfig = {0}; + TIM_IC_InitTypeDef sConfigIC = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + + halTIM.Instance = instance; + halTIM.Init.Prescaler = 0; + halTIM.Init.CounterMode = TIM_COUNTERMODE_UP; + halTIM.Init.Period = 4294967295; + halTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + halTIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + + + HAL_TIM_Base_Init(&halTIM); + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + HAL_TIM_PWM_Init(&halTIM); + HAL_TIM_ConfigClockSource(&halTIM, &sClockSourceConfig); + HAL_TIM_IC_Init(&halTIM); + + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = triggerSource; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; + sSlaveConfig.TriggerFilter = 0; + + HAL_TIM_SlaveConfigSynchro(&halTIM, &sSlaveConfig); + + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + sConfigIC.ICFilter = 0; + + // HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, directChannel); + + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + + //HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, indirectChannel); + + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + + HAL_TIMEx_MasterConfigSynchronization(&halTIM, &sMasterConfig); + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + __HAL_RCC_GPIOA_CLK_ENABLE(); + Pin myPins[] = {pin}; + uint8_t numOfPins = 1; + + GPIO_InitStruct.Pin = pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = altFunc; + HAL_GPIO_Init(gpioType, &GPIO_InitStruct); +} + + + +uint32_t PWM_INPUTf3xx::getDutyCycle() { + return dutyCycle; +} + +uint32_t PWM_INPUTf3xx::getPeriod() { + return period; +} + +uint32_t PWM_INPUTf3xx::getFrequency() { + return frequency; +} + + + + + + + +} From 508a7b61e15b203495eff5dfbc1ca6075f7e19de Mon Sep 17 00:00:00 2001 From: Xander B Date: Fri, 5 Sep 2025 22:49:52 -0400 Subject: [PATCH 08/22] moved PWM Input setup into f3xx, need to clean up main sample and add remaining pins to f3xx --- .../core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 27 +++- src/core/io/PWM_INPUT.cpp | 2 +- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 124 +++++++++++++++--- 3 files changed, 124 insertions(+), 29 deletions(-) diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index 3a48c86c..43817299 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -10,12 +10,17 @@ namespace core::io { + +/** + * PWM input for f3 + * Measures the duty cycle, frequency, and period of a PWM signal on a pin + */ class PWM_INPUTf3xx : public PWM_INPUT { public: /** - * Setup the given pin for PWM usage. + * Setup the given pin for PWM Input usage. * - * @param pin[in] The pin to setup for PWM + * @param pin[in] The pin to setup for PWM Input Capture */ PWM_INPUTf3xx(Pin pin); @@ -25,13 +30,21 @@ class PWM_INPUTf3xx : public PWM_INPUT { uint32_t getFrequency(); + /// Called from HAL_TIM_IC_CaptureCallback to update measurements + void handleCapture(TIM_HandleTypeDef* htim); + + /// Provides access to HAL handle for IRQ forwarding + TIM_HandleTypeDef* getHandle() { return &halTIM; } + private: /// HAL timer representation - TIM_HandleTypeDef halTIM; - /// Channel identification - uint32_t halTIMChannelID; - /// HAL channel representation - TIM_OC_InitTypeDef halChannel; + TIM_HandleTypeDef halTIM; //hal timer handle + /// Channel for rising edge measurement + uint32_t directChannel; + /// Channel for falling edge measurement + uint32_t indirectChannel; + ///active channel + uint32_t activeChannel; }; } // namespace core::io diff --git a/src/core/io/PWM_INPUT.cpp b/src/core/io/PWM_INPUT.cpp index e6879c50..7fa0099f 100644 --- a/src/core/io/PWM_INPUT.cpp +++ b/src/core/io/PWM_INPUT.cpp @@ -2,7 +2,7 @@ namespace core::io { -PWM_INPUT::PWM_INPUT(core::io::Pin pin) { +PWM_INPUT::PWM_INPUT(Pin pin) { //core::io::Pin pin this->pin = pin; this->dutyCycle = 0; this->period = 0; diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index c995eff8..85619c3c 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -5,13 +5,66 @@ namespace core::io { +// Global pointer to the active instance (one at a time) +static PWM_INPUTf3xx* activePwmInput = nullptr; + +/** + * Get timer instance, direct channel, indirect channel, and alternate function + * associated with a pin. This information is pulled from the STM32F302x8 documentation. + * F302 pinout and alternate functions specifically for PWM_INPUT can be found in the drive. + * + @param pin The pin to check the instance of +* @param instance The timer instance to assign to +* @param directChannel The direct channel to assign to +* @param indirectChannel The indirect channel to assign to +* @param alternateFunction The GPIO identifier for the function of the pin +* @param irqNumber IRQ number for NVIC +* @param activeChannel HAL enum for which channel will fire the interrupt + */ + +static void getInputInstance(Pin pin, + TIM_TypeDef** instance, + uint32_t* directChannel, + uint32_t* indirectChannel, + uint32_t* alternateFunction, + uint32_t* triggerSource, + IRQn_Type* irqNumber, + uint32_t* activeChannel) { + switch (pin) { +#if defined(STM32F302x8) + case Pin::PA_2: + *instance = TIM1; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF2_TIM1; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + // TODO: Add other pins like in PWMf3xx::getInstance +#endif + default: + *instance = NULL; + *directChannel = -1; + *indirectChannel = -1; + *alternateFunction = -1; + *triggerSource = -1; + *irqNumber = (IRQn_Type)-1; //TODO fix this, find actual default + *activeChannel = -1; + + } +} -PWM_INPUTf3xx::PWM_INPUTf3xx(core::io::Pin pin) { +PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { TIM_TypeDef* instance; uint32_t alternateFunction; - //getInstance(pin, &instance, &halTIMChannelID, &alternateFunction); + uint32_t triggerSource; + IRQn_Type irqNumber; + + getInputInstance(pin, &instance, &directChannel, &indirectChannel, &alternateFunction, &triggerSource, + &irqNumber, &activeChannel); if (instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); @@ -26,61 +79,90 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(core::io::Pin pin) { TIM_IC_InitTypeDef sConfigIC = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; - + //initilize timer base halTIM.Instance = instance; halTIM.Init.Prescaler = 0; halTIM.Init.CounterMode = TIM_COUNTERMODE_UP; halTIM.Init.Period = 4294967295; halTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; halTIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - - HAL_TIM_Base_Init(&halTIM); + + //configure clock src sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_PWM_Init(&halTIM); HAL_TIM_ConfigClockSource(&halTIM, &sClockSourceConfig); HAL_TIM_IC_Init(&halTIM); + //slave reset mode, used to measure period sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; sSlaveConfig.InputTrigger = triggerSource; sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; sSlaveConfig.TriggerFilter = 0; - HAL_TIM_SlaveConfigSynchro(&halTIM, &sSlaveConfig); + //configure direct, rising channel sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; + HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, directChannel); - // HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, directChannel); - + //configure indirect, falling channel sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; - - //HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, indirectChannel); + HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, indirectChannel); sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - HAL_TIMEx_MasterConfigSynchronization(&halTIM, &sMasterConfig); - GPIO_InitTypeDef GPIO_InitStruct = {0}; + //setup GPIO + GPIO_InitTypeDef gpioInit = {0}; + Pin myPins[] = { pin }; + uint8_t numOfPins = 1; + + GPIOf3xx::gpioStateInit(&gpioInit,myPins,numOfPins,GPIO_MODE_AF_PP,GPIO_NOPULL, + GPIO_SPEED_FREQ_LOW,alternateFunction); + - __HAL_RCC_GPIOA_CLK_ENABLE(); - Pin myPins[] = {pin}; - uint8_t numOfPins = 1; + //configure NVIC + HAL_NVIC_SetPriority(irqNumber, 0, 0); + HAL_NVIC_EnableIRQ(irqNumber); + // enable interrupt src + HAL_TIM_IC_Start_IT(&halTIM, directChannel); // main channel + HAL_TIM_IC_Start(&halTIM, indirectChannel); // indirect channel - GPIO_InitStruct.Pin = pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = altFunc; - HAL_GPIO_Init(gpioType, &GPIO_InitStruct); + activePwmInput = this; // Register this instance as active } +void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { + if (htim->Channel == activeChannel) // If the interrupt is triggered by channel 1 + { + // Read the IC value + uint32_t inputCaptureValue = HAL_TIM_ReadCapturedValue(htim, directChannel); + + if (inputCaptureValue != 0) // first value is zero, non zero is period + { + // calculate the Duty Cycle + // signal high time/ period = duty cycle + dutyCycle = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / inputCaptureValue; + + frequency = SystemCoreClock / inputCaptureValue; // APB1 Timer clocks/period = F + period = inputCaptureValue; + } + } +} + +// Global HAL callback -> forwards to the single active instance +extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { + if (activePwmInput) { + activePwmInput->handleCapture(htim); + } +} + uint32_t PWM_INPUTf3xx::getDutyCycle() { return dutyCycle; From 82775ef0a60a30e18b76c0731de2044fa00dcf48 Mon Sep 17 00:00:00 2001 From: Xander B Date: Sat, 6 Sep 2025 00:44:10 -0400 Subject: [PATCH 09/22] added getPWM_INPUT to manager.hpp, removed all setup from main sample, added all the correct pins to PWM_INPUTF3xx.cpp. Should be good for testing --- include/core/io/PWM_INPUT.hpp | 2 +- include/core/manager.hpp | 19 +++ samples/pwm_input/main.cpp | 165 ++------------------ src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 103 +++++++++++- 4 files changed, 131 insertions(+), 158 deletions(-) diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp index bf8e01a4..2804fe0d 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWM_INPUT.hpp @@ -53,4 +53,4 @@ class PWM_INPUT { } // namespace core::io -#endif // EVT_PWM_INPUT_HPP +#endif diff --git a/include/core/manager.hpp b/include/core/manager.hpp index 2b6bd231..6a982eeb 100644 --- a/include/core/manager.hpp +++ b/include/core/manager.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ #define IWDG_SUPPORTED #define MCU_SUPPORTED #define PWM_SUPPORTED + #define PWM_INPUT_SUPPORTED #define RTC_SUPPORTED #define SPI_SUPPORTED #define UART_SUPPORTED @@ -32,6 +34,7 @@ #include #include #include + #include #include #include #include @@ -240,6 +243,22 @@ PWM& getPWM() { } #endif +/** + * Get an instance of a PWM_INPUT pin. + * + * @param[in] pin The pin to attach to the PWM_INPUT. + */ +#ifdef PWM_INPUT_SUPPORTED +template +PWM_INPUT& getPWM_INPUT() { + #ifdef STM32F3xx + static PWM_INPUTf3xx pwm_input(pin); + return pwm_input; + #endif +} +#endif + + /** * Get an instance of a UART. * diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 0f45840f..5e84822c 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -1,7 +1,8 @@ // Xander 2/3/2025. + +#include #include -#include #include #include #include @@ -10,61 +11,12 @@ namespace io = core::io; namespace time = core::time; namespace log = core::log; -// Defines for testing --------------------------------------------------------------------------------- -//Channel defines----- -#define directChannel TIM_CHANNEL_1 // TIM_CHANNEL_1 -#define activeDirectChannel HAL_TIM_ACTIVE_CHANNEL_1 // HAL_TIM_ACTIVE_CHANNEL_1 -#define indirectChannel TIM_CHANNEL_2 // TIM_CHANNEL_2 -#define triggerSource TIM_TS_TI1FP1 // TIM_TS_TI1FP1 -#define gpioClkEnable __HAL_RCC_GPIOA_CLK_ENABLE(); //__HAL_RCC_GPIOA_CLK_ENABLE(); -#define thePin GPIO_PIN_2 // GPIO_PIN_0 -#define altFunc GPIO_AF9_TIM15 // GPIO_AF1_TIM2 -#define gpioType GPIOA // GPIOA -//Timer Defines----- -#define TIMNum TIM15 //TIM 2 -#define IRQHandler TIM1_BRK_TIM15_IRQHandler //TIM2_IRQHandler -#define htimNum htim15 //htim2 -#define IRQNum TIM1_BRK_TIM15_IRQn //TIM2_IRQn -#define clkEnable __HAL_RCC_TIM15_CLK_ENABLE(); //__HAL_RCC_TIM2_CLK_ENABLE(); -//------------------------------------------------------------------------------------------------------- - - - -TIM_HandleTypeDef htimNum; - - - -static void MX_GPIO_Init(void); -static void MX_TIM2_Init(void); - -void Error_Handler(void); -// IRQ handler for TIM2 -extern "C" void IRQHandler (void) { - HAL_TIM_IRQHandler(&htimNum); -} - -uint32_t ICValue = 0; +uint32_t Period = 0; //ICValue uint32_t Frequency = 0; -uint32_t Duty = 0; +uint32_t DutyCycle = 0; -void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { - log::LOGGER.log(log::Logger::LogLevel::DEBUG, "CAPTURE_CALLBACK!!"); - if (htim->Channel == activeDirectChannel) // If the interrupt is triggered by channel 1 - { - // Read the IC value - ICValue = HAL_TIM_ReadCapturedValue(htim, directChannel); - if (ICValue != 0) // first value is zero, non zero is period - { - // calculate the Duty Cycle - // signal high time/ period = duty cycle - Duty = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / ICValue; - - Frequency = SystemCoreClock / ICValue; // APB1 Timer clocks/period = F - } - } -} int main(void) { // Initialize system @@ -76,113 +28,20 @@ int main(void) { log::LOGGER.setUART(&uart); log::LOGGER.setLogLevel(log::Logger::LogLevel::DEBUG); - /* Initialize all configured peripherals */ - MX_TIM2_Init(); + uart.printf("STARTING PWM INPUT INPUT CAPTURE\n\r"); + + io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); - uart.printf("START INPUT CAPTURE\n\r"); - // input capture - // enable TIM2 interrupt, set priority - HAL_NVIC_SetPriority(IRQNum, 0, 0); - HAL_NVIC_EnableIRQ(IRQNum); - // enable interrupt src - HAL_TIM_IC_Start_IT(&htimNum, directChannel); // main channel - HAL_TIM_IC_Start(&htimNum, indirectChannel); // indirect channel - uart.printf("END INPUT CAPTURE\n\r"); while (1) { time::wait(1000); - uart.printf("\n\rICValue: %d\n\r", ICValue); + Period = pwmInput.getPeriod(); + Frequency = pwmInput.getFrequency(); + DutyCycle = pwmInput.getDutyCycle(); + uart.printf("\n\rPeriod: %d\n\r", Period); uart.printf("\n\rFrequency: %d\n\r", Frequency) ; - uart.printf("\n\rDuty: %d\n\r", Duty); + uart.printf("\n\rDuty: %d\n\r", DutyCycle); uart.printf("\n\r----------------------------------\n\r"); } } -/** - * @brief System Clock Configuration - * @retval None - */ - -static void MX_TIM2_Init(void) { - /* USER CODE BEGIN TIM2_Init 0 */ - log::LOGGER.log(log::Logger::LogLevel::DEBUG, "TIM2_INIT"); - /* USER CODE END TIM2_Init 0 */ - - TIM_ClockConfigTypeDef sClockSourceConfig = {0}; - TIM_SlaveConfigTypeDef sSlaveConfig = {0}; - TIM_IC_InitTypeDef sConfigIC = {0}; - TIM_MasterConfigTypeDef sMasterConfig = {0}; - - /* USER CODE BEGIN TIM2_Init 1 */ - //__HAL_RCC_TIM2_CLK_ENABLE(); - clkEnable; - /* USER CODE END TIM2_Init 1 */ - htimNum.Instance = TIMNum; - htimNum.Init.Prescaler = 0; - htimNum.Init.CounterMode = TIM_COUNTERMODE_UP; - htimNum.Init.Period = 4294967295; - htimNum.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htimNum.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if (HAL_TIM_Base_Init(&htimNum) != HAL_OK) { - Error_Handler(); - } - sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if (HAL_TIM_ConfigClockSource(&htimNum, &sClockSourceConfig) != HAL_OK) { - Error_Handler(); - } - if (HAL_TIM_IC_Init(&htimNum) != HAL_OK) { - Error_Handler(); - } - sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; - sSlaveConfig.InputTrigger = triggerSource; - sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; - sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; - sSlaveConfig.TriggerFilter = 0; - if (HAL_TIM_SlaveConfigSynchro(&htimNum, &sSlaveConfig) != HAL_OK) { - Error_Handler(); - } - sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; - sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; - sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; - sConfigIC.ICFilter = 0; - if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, directChannel) != HAL_OK) { //direct - Error_Handler(); - } - sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; - sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; - if (HAL_TIM_IC_ConfigChannel(&htimNum, &sConfigIC, indirectChannel) != HAL_OK) { - Error_Handler(); - } - sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; - sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if (HAL_TIMEx_MasterConfigSynchronization(&htimNum, &sMasterConfig) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN TIM2_Init 2 */ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - //__HAL_RCC_GPIOA_CLK_ENABLE(); - gpioClkEnable - /**TIM2 GPIO Configuration - PA0 ------> TIM2_CH1 - */ - - GPIO_InitStruct.Pin = thePin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = altFunc; - HAL_GPIO_Init(gpioType, &GPIO_InitStruct); - /* USER CODE END TIM2_Init 2 */ -} - -void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) { - // TODO Report Hal error return state - log::LOGGER.log(log::Logger::LogLevel::DEBUG, "Bad"); - } - /* USER CODE END Error_Handler_Debug */ -} diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 85619c3c..08dcaaa9 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -32,7 +32,8 @@ static void getInputInstance(Pin pin, uint32_t* activeChannel) { switch (pin) { #if defined(STM32F302x8) - case Pin::PA_2: + // TIM 1 Channel 1 Direct, Channel 2 Indirect + case Pin::PC_0: *instance = TIM1; *directChannel = TIM_CHANNEL_1; *indirectChannel = TIM_CHANNEL_2; @@ -41,7 +42,101 @@ static void getInputInstance(Pin pin, *irqNumber = TIM1_CC_IRQn; *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; break; - // TODO: Add other pins like in PWMf3xx::getInstance + case Pin::PA_8: + *instance = TIM1; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF6_TIM1; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + // TIM 1 Channel 2 Direct, Channel 1 Indirect + case Pin::PC_1: + *instance = TIM1; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF2_TIM1; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; + // TIM 2 Channel 1 Direct, Channel 2 Indirect + case Pin::PA_0: + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + case Pin::PA_5: + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + case Pin::PA_15: + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + // TIM 2 Channel 2 Direct, Channel 1 Indirect + case Pin::PB_3: + *instance = TIM2; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; + // TIM 15 Channel 1 Direct, Channel 2 Indirect + case Pin::PA_2: + *instance = TIM15; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF9_TIM15; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + case Pin::PB_14: + *instance = TIM15; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM15; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; + // TIM 15 Channel 2 Direct, Channel 1 Indirect + case Pin::PA_3: + *instance = TIM15; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF9_TIM15; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; + case Pin::PB_15: + *instance = TIM15; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF1_TIM15; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; #endif default: *instance = NULL; @@ -141,7 +236,7 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { if (htim->Channel == activeChannel) // If the interrupt is triggered by channel 1 { - // Read the IC value + // Read the IC value (period) uint32_t inputCaptureValue = HAL_TIM_ReadCapturedValue(htim, directChannel); if (inputCaptureValue != 0) // first value is zero, non zero is period @@ -150,7 +245,7 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { // signal high time/ period = duty cycle dutyCycle = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / inputCaptureValue; - frequency = SystemCoreClock / inputCaptureValue; // APB1 Timer clocks/period = F + frequency = SystemCoreClock / inputCaptureValue; period = inputCaptureValue; } } From e3696745786a35ec711ac5892851ab9513330e46 Mon Sep 17 00:00:00 2001 From: Xander B Date: Sat, 6 Sep 2025 12:44:29 -0400 Subject: [PATCH 10/22] Works, need to clean it up a bit and add comments. --- .../core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 4 +- samples/pwm_input/main.cpp | 3 +- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 39 ++++++++++++++++--- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index 43817299..23880fb7 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -34,7 +34,8 @@ class PWM_INPUTf3xx : public PWM_INPUT { void handleCapture(TIM_HandleTypeDef* htim); /// Provides access to HAL handle for IRQ forwarding - TIM_HandleTypeDef* getHandle() { return &halTIM; } + //TIM_HandleTypeDef* getHandle() { return &halTIM; } + TIM_HandleTypeDef* getHandle(); private: /// HAL timer representation @@ -45,6 +46,7 @@ class PWM_INPUTf3xx : public PWM_INPUT { uint32_t indirectChannel; ///active channel uint32_t activeChannel; + }; } // namespace core::io diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 5e84822c..0088862f 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -30,8 +30,7 @@ int main(void) { uart.printf("STARTING PWM INPUT INPUT CAPTURE\n\r"); - io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); - + io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { time::wait(1000); diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 08dcaaa9..7fbdcd53 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -233,6 +233,38 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { } +TIM_HandleTypeDef* PWM_INPUTf3xx::getHandle() { + return &halTIM; +} + + +extern "C" void TIM1_CC_IRQHandler(void) { + if (activePwmInput) { + HAL_TIM_IRQHandler(activePwmInput->getHandle()); + } +} + +extern "C" void TIM2_IRQHandler(void) { + if (activePwmInput) { + HAL_TIM_IRQHandler(activePwmInput->getHandle()); + } +} + +extern "C" void TIM1_BRK_TIM15_IRQHandler(void) { + if (activePwmInput) { + HAL_TIM_IRQHandler(activePwmInput->getHandle()); + } +} + + +// Global HAL callback -> forwards to the single active instance +extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { + if (activePwmInput) { + activePwmInput->handleCapture(htim); + } +} + + void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { if (htim->Channel == activeChannel) // If the interrupt is triggered by channel 1 { @@ -251,12 +283,7 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { } } -// Global HAL callback -> forwards to the single active instance -extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { - if (activePwmInput) { - activePwmInput->handleCapture(htim); - } -} + uint32_t PWM_INPUTf3xx::getDutyCycle() { From 9b514ca99a8a177626492c6744f46f823e1aead5 Mon Sep 17 00:00:00 2001 From: Xander B Date: Mon, 8 Sep 2025 17:27:23 -0400 Subject: [PATCH 11/22] Added comments where needed --- include/core/io/PWM_INPUT.hpp | 16 +++++++++------- include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 5 ++--- samples/pwm_input/main.cpp | 17 +++++++---------- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 15 ++++++--------- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp index 2804fe0d..40f070fb 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWM_INPUT.hpp @@ -6,37 +6,39 @@ namespace core::io { -// Different pins are hardware specific +// Forward declarations: +// The different pins are hardware specific. Forward declaration to allow +// at compilation time the decision of which pins should be used. enum class Pin; class PWM_INPUT { public: /** - * Setup the given pin for PWM usage. + * Setup the given pin for PWM_INPUT usage. * - * @param[in] pin The pin to setup for PWM + * @param[in] pin The pin to setup for PWM_INPUT */ PWM_INPUT(Pin pin); /** * Get the current duty cycle. * - * @return The duty cycle the PWM input is operating at. + * @return The duty cycle of the PWM signal being read, as a percentage. */ virtual uint32_t getDutyCycle() = 0; /** * Get the current period. * - * @return The period the PWM input is operating at in microseconds. + * @return The period the PWM signal being read is operating at in timer ticks. */ virtual uint32_t getPeriod() = 0; /** - * Get the current period. + * Get the current frequency. * - * @return The frequency the PWM input is operating at in Hz. + * @return The frequency the PWM signal being read is operating at in Hz. */ virtual uint32_t getFrequency() = 0; diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index 23880fb7..be4fa3e4 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -30,11 +30,10 @@ class PWM_INPUTf3xx : public PWM_INPUT { uint32_t getFrequency(); - /// Called from HAL_TIM_IC_CaptureCallback to update measurements + /// Called from HAL_TIM_IC_CaptureCallback to update duty cycle, period, and frequency void handleCapture(TIM_HandleTypeDef* htim); /// Provides access to HAL handle for IRQ forwarding - //TIM_HandleTypeDef* getHandle() { return &halTIM; } TIM_HandleTypeDef* getHandle(); private: @@ -51,4 +50,4 @@ class PWM_INPUTf3xx : public PWM_INPUT { } // namespace core::io -#endif // EVT_PWM_INPUTF3XX_HPP +#endif diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 0088862f..bf344a01 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -1,15 +1,15 @@ - -// Xander 2/3/2025. +/** + * Example of PWM input. + * This sample will measure the duty cycle, frequency, and period of a PWM signal. + */ #include #include #include -#include #include namespace io = core::io; namespace time = core::time; -namespace log = core::log; uint32_t Period = 0; //ICValue @@ -21,19 +21,15 @@ uint32_t DutyCycle = 0; int main(void) { // Initialize system core::platform::init(); + // Setup UART io::UART& uart = io::getUART(9600); - // setup logger - log::LOGGER.setUART(&uart); - log::LOGGER.setLogLevel(log::Logger::LogLevel::DEBUG); - - uart.printf("STARTING PWM INPUT INPUT CAPTURE\n\r"); + uart.printf("Starting PWM input capture\n\r"); io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { - time::wait(1000); Period = pwmInput.getPeriod(); Frequency = pwmInput.getFrequency(); DutyCycle = pwmInput.getDutyCycle(); @@ -41,6 +37,7 @@ int main(void) { uart.printf("\n\rFrequency: %d\n\r", Frequency) ; uart.printf("\n\rDuty: %d\n\r", DutyCycle); uart.printf("\n\r----------------------------------\n\r"); + time::wait(1000); } } diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 7fbdcd53..e315bf66 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -9,8 +9,9 @@ namespace core::io { static PWM_INPUTf3xx* activePwmInput = nullptr; /** - * Get timer instance, direct channel, indirect channel, and alternate function - * associated with a pin. This information is pulled from the STM32F302x8 documentation. + * Get timer instance, direct channel, indirect channel, alternate function, + * triggerSource, irqNumber, and activeChannel associated with a pin. + * This information is pulled from the STM32F302x8 documentation. * F302 pinout and alternate functions specifically for PWM_INPUT can be found in the drive. * @param pin The pin to check the instance of @@ -144,7 +145,7 @@ static void getInputInstance(Pin pin, *indirectChannel = -1; *alternateFunction = -1; *triggerSource = -1; - *irqNumber = (IRQn_Type)-1; //TODO fix this, find actual default + *irqNumber = (IRQn_Type)-1; *activeChannel = -1; } @@ -266,17 +267,15 @@ extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { - if (htim->Channel == activeChannel) // If the interrupt is triggered by channel 1 + if (htim->Channel == activeChannel) // If the interrupt is triggered by the active channel { // Read the IC value (period) uint32_t inputCaptureValue = HAL_TIM_ReadCapturedValue(htim, directChannel); if (inputCaptureValue != 0) // first value is zero, non zero is period { - // calculate the Duty Cycle - // signal high time/ period = duty cycle + // signal high (time/ period) * 100 = duty cycle as percent dutyCycle = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / inputCaptureValue; - frequency = SystemCoreClock / inputCaptureValue; period = inputCaptureValue; } @@ -284,8 +283,6 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { } - - uint32_t PWM_INPUTf3xx::getDutyCycle() { return dutyCycle; } From a7f164ce2cb61ccfad0e72ef09a4903415f6b398 Mon Sep 17 00:00:00 2001 From: Xander B Date: Mon, 8 Sep 2025 20:12:12 -0400 Subject: [PATCH 12/22] added comments, broke something --- samples/pwm_input/main.cpp | 3 +-- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 6 ------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index bf344a01..a813113d 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -27,7 +27,7 @@ int main(void) { uart.printf("Starting PWM input capture\n\r"); - io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); + io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { Period = pwmInput.getPeriod(); @@ -40,4 +40,3 @@ int main(void) { time::wait(1000); } } - diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index e315bf66..8fa996de 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -295,10 +295,4 @@ uint32_t PWM_INPUTf3xx::getFrequency() { return frequency; } - - - - - - } From d4a008b93b4102c764041d4d826444736a6bac61 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 11 Sep 2025 20:33:12 -0400 Subject: [PATCH 13/22] All pins/timers tested and working with 1000 micro second period --- samples/pwm_input/main.cpp | 2 +- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index a813113d..36cddd35 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -27,7 +27,7 @@ int main(void) { uart.printf("Starting PWM input capture\n\r"); - io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); + io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { Period = pwmInput.getPeriod(); diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 8fa996de..90d5fb72 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -12,7 +12,8 @@ static PWM_INPUTf3xx* activePwmInput = nullptr; * Get timer instance, direct channel, indirect channel, alternate function, * triggerSource, irqNumber, and activeChannel associated with a pin. * This information is pulled from the STM32F302x8 documentation. - * F302 pinout and alternate functions specifically for PWM_INPUT can be found in the drive. + * + * NOTE: PA_2 and PA_3 are used for UART Tx and Rx respectively * @param pin The pin to check the instance of * @param instance The timer instance to assign to @@ -101,7 +102,7 @@ static void getInputInstance(Pin pin, *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; break; // TIM 15 Channel 1 Direct, Channel 2 Indirect - case Pin::PA_2: + case Pin::PA_2: //PA2 is UART tx, don't use if using UART *instance = TIM15; *directChannel = TIM_CHANNEL_1; *indirectChannel = TIM_CHANNEL_2; @@ -120,7 +121,7 @@ static void getInputInstance(Pin pin, *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; break; // TIM 15 Channel 2 Direct, Channel 1 Indirect - case Pin::PA_3: + case Pin::PA_3: //PA3 is UART rx, don't use if using UART *instance = TIM15; *directChannel = TIM_CHANNEL_2; *indirectChannel = TIM_CHANNEL_1; @@ -162,6 +163,13 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { getInputInstance(pin, &instance, &directChannel, &indirectChannel, &alternateFunction, &triggerSource, &irqNumber, &activeChannel); + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_SlaveConfigTypeDef sSlaveConfig = {0}; + TIM_IC_InitTypeDef sConfigIC = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + if (instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); } else if (instance == TIM2) { @@ -170,10 +178,6 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { __HAL_RCC_TIM15_CLK_ENABLE(); } - TIM_ClockConfigTypeDef sClockSourceConfig = {0}; - TIM_SlaveConfigTypeDef sSlaveConfig = {0}; - TIM_IC_InitTypeDef sConfigIC = {0}; - TIM_MasterConfigTypeDef sMasterConfig = {0}; //initilize timer base halTIM.Instance = instance; @@ -186,7 +190,6 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { //configure clock src sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - HAL_TIM_PWM_Init(&halTIM); HAL_TIM_ConfigClockSource(&halTIM, &sClockSourceConfig); HAL_TIM_IC_Init(&halTIM); From 441c743db272e143fff32cb23d191a9ec2923b15 Mon Sep 17 00:00:00 2001 From: GitHub Build Date: Fri, 12 Sep 2025 00:43:44 +0000 Subject: [PATCH 14/22] Applied Formatting Changes During GitHub Build --- .../core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 6 +- include/core/manager.hpp | 3 +- samples/pwm_input/main.cpp | 11 +- samples/rtos/threadx-demo/main.cpp | 10 +- src/core/dev/LCD.cpp | 10 +- src/core/io/PWM_INPUT.cpp | 2 +- src/core/io/platform/f3xx/ADCf3xx.cpp | 2 +- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 248 +++++++++--------- src/core/io/platform/f4xx/ADCf4xx.cpp | 2 +- src/core/rtos/tsio/ThreadUART.cpp | 2 +- 10 files changed, 139 insertions(+), 157 deletions(-) diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index be4fa3e4..5eedfb02 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -10,7 +10,6 @@ namespace core::io { - /** * PWM input for f3 * Measures the duty cycle, frequency, and period of a PWM signal on a pin @@ -38,14 +37,13 @@ class PWM_INPUTf3xx : public PWM_INPUT { private: /// HAL timer representation - TIM_HandleTypeDef halTIM; //hal timer handle + TIM_HandleTypeDef halTIM; // hal timer handle /// Channel for rising edge measurement uint32_t directChannel; /// Channel for falling edge measurement uint32_t indirectChannel; - ///active channel + /// active channel uint32_t activeChannel; - }; } // namespace core::io diff --git a/include/core/manager.hpp b/include/core/manager.hpp index 6a982eeb..e78c1341 100644 --- a/include/core/manager.hpp +++ b/include/core/manager.hpp @@ -33,8 +33,8 @@ #include #include #include - #include #include + #include #include #include #include @@ -258,7 +258,6 @@ PWM_INPUT& getPWM_INPUT() { } #endif - /** * Get an instance of a UART. * diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 36cddd35..6a1e8c01 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -11,12 +11,9 @@ namespace io = core::io; namespace time = core::time; - -uint32_t Period = 0; //ICValue +uint32_t Period = 0; // ICValue uint32_t Frequency = 0; -uint32_t DutyCycle = 0; - - +uint32_t DutyCycle = 0; int main(void) { // Initialize system @@ -30,11 +27,11 @@ int main(void) { io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { - Period = pwmInput.getPeriod(); + Period = pwmInput.getPeriod(); Frequency = pwmInput.getFrequency(); DutyCycle = pwmInput.getDutyCycle(); uart.printf("\n\rPeriod: %d\n\r", Period); - uart.printf("\n\rFrequency: %d\n\r", Frequency) ; + uart.printf("\n\rFrequency: %d\n\r", Frequency); uart.printf("\n\rDuty: %d\n\r", DutyCycle); uart.printf("\n\r----------------------------------\n\r"); time::wait(1000); diff --git a/samples/rtos/threadx-demo/main.cpp b/samples/rtos/threadx-demo/main.cpp index 67747ae4..3b58f8dc 100644 --- a/samples/rtos/threadx-demo/main.cpp +++ b/samples/rtos/threadx-demo/main.cpp @@ -52,7 +52,7 @@ typedef struct counters { * Struct that holds the arguments for the thread that generates the numbers */ struct numberGenThreadArgs { - rtos::Queue* outputQueue; // The queue of numbers that the number gen thread add it's generated number to + rtos::Queue* outputQueue; // The queue of numbers that the number gen thread add it's generated number to rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or printing // to uart at the same time these shouldn't necessarily need to be mutually exclusive, @@ -68,17 +68,17 @@ struct numberGenThreadArgs { * Struct that holds the arguments for all other threads */ struct numberConsumerThreadArgs { - rtos::Queue* inputQueue; // The queue that the threads will pull values that the number gen thread adds + rtos::Queue* inputQueue; // The queue that the threads will pull values that the number gen thread adds - rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or - // printing to uart + rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or + // printing to uart rtos::tsio::ThreadUART* threadUART; // The instance of ThreadUART that this thread will use to print. rtos::EventFlags* eventFlags; // the EventFlags that the number consumer threads will use to show they have gotten a // number, which will trigger the eventFlagThread to run it's own method. - uint8_t num; // What number this thread is + uint8_t num; // What number this thread is counters_t* counters; // the struct of counters for the number consumer threads to increase their counters when they // get a number diff --git a/src/core/dev/LCD.cpp b/src/core/dev/LCD.cpp index adfb86b2..41c78cef 100644 --- a/src/core/dev/LCD.cpp +++ b/src/core/dev/LCD.cpp @@ -78,7 +78,7 @@ void LCD::driveColumn(uint8_t page, uint8_t colUp, uint8_t colLow, uint8_t data) } void LCD::clearLCD() { - uint8_t page = 0xB0; // The starting page + uint8_t page = 0xB0; // The starting page this->commandWrite(0x40); // Display start address + 0x40 for (uint8_t i = 0; i < 8; i++) { // 64 pixel display / 8 pixels per page = 8 pages @@ -88,7 +88,7 @@ void LCD::clearLCD() { for (uint8_t j = 0; j < screenSizeX; j++) { // 128 columns wide this->dataWrite(0x00); // Write clear pixels } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); } @@ -110,7 +110,7 @@ void LCD::clearArea(uint8_t width, uint8_t numPages, uint8_t page, uint8_t colum this->dataWrite(0x00); // Write Clear Pixels } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); // Finish Writing } @@ -126,7 +126,7 @@ void LCD::setEntireScreenBitMap(const uint8_t* bitMap) { this->dataWrite(*bitMap); // write pixels from bitmap bitMap++; // Advance the bitmap pointer by one. This means we can just grab the last one the next loop. } - page++; // after 128 columns, go to next page + page++; // after 128 columns, go to next page } this->commandWrite(0xAF); } @@ -149,7 +149,7 @@ void LCD::displayBitMapInArea(uint8_t* bitMap, uint8_t bitMapWidth, uint8_t numP bitMap++; // Advance the bitmap pointer by one. This means we can just grab the last one the next loop. } - page++; // After 128 columns, go to next page + page++; // After 128 columns, go to next page } this->commandWrite(0xAF); // Finish writing } diff --git a/src/core/io/PWM_INPUT.cpp b/src/core/io/PWM_INPUT.cpp index 7fa0099f..13d62f8e 100644 --- a/src/core/io/PWM_INPUT.cpp +++ b/src/core/io/PWM_INPUT.cpp @@ -2,7 +2,7 @@ namespace core::io { -PWM_INPUT::PWM_INPUT(Pin pin) { //core::io::Pin pin +PWM_INPUT::PWM_INPUT(Pin pin) { // core::io::Pin pin this->pin = pin; this->dutyCycle = 0; this->period = 0; diff --git a/src/core/io/platform/f3xx/ADCf3xx.cpp b/src/core/io/platform/f3xx/ADCf3xx.cpp index a1286081..dbf8d8f4 100644 --- a/src/core/io/platform/f3xx/ADCf3xx.cpp +++ b/src/core/io/platform/f3xx/ADCf3xx.cpp @@ -185,7 +185,7 @@ void ADCf3xx::addChannel(uint8_t rank) { default: channelStruct = {}; // sets all variables to 0 log::LOGGER.log(log::Logger::LogLevel::ERROR, "INVALID PIN 0x%x!!", pin); - break; // Should never get here + break; // Should never get here } // Subtract 1 because rank starts at 1 diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 90d5fb72..4c1bef4d 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -4,7 +4,6 @@ namespace core::io { - // Global pointer to the active instance (one at a time) static PWM_INPUTf3xx* activePwmInput = nullptr; @@ -24,152 +23,148 @@ static PWM_INPUTf3xx* activePwmInput = nullptr; * @param activeChannel HAL enum for which channel will fire the interrupt */ -static void getInputInstance(Pin pin, - TIM_TypeDef** instance, - uint32_t* directChannel, - uint32_t* indirectChannel, - uint32_t* alternateFunction, - uint32_t* triggerSource, - IRQn_Type* irqNumber, +static void getInputInstance(Pin pin, TIM_TypeDef** instance, uint32_t* directChannel, uint32_t* indirectChannel, + uint32_t* alternateFunction, uint32_t* triggerSource, IRQn_Type* irqNumber, uint32_t* activeChannel) { switch (pin) { #if defined(STM32F302x8) // TIM 1 Channel 1 Direct, Channel 2 Indirect case Pin::PC_0: - *instance = TIM1; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; + *instance = TIM1; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; *alternateFunction = GPIO_AF2_TIM1; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM1_CC_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; case Pin::PA_8: - *instance = TIM1; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF6_TIM1; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM1_CC_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *instance = TIM1; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF6_TIM1; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; // TIM 1 Channel 2 Direct, Channel 1 Indirect case Pin::PC_1: - *instance = TIM1; - *directChannel = TIM_CHANNEL_2; - *indirectChannel = TIM_CHANNEL_1; - *alternateFunction = GPIO_AF2_TIM1; - *triggerSource = TIM_TS_TI2FP2; - *irqNumber = TIM1_CC_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; - break; + *instance = TIM1; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF2_TIM1; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_CC_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; // TIM 2 Channel 1 Direct, Channel 2 Indirect case Pin::PA_0: - *instance = TIM2; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF1_TIM2; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM2_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; case Pin::PA_5: - *instance = TIM2; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF1_TIM2; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM2_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; case Pin::PA_15: - *instance = TIM2; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF1_TIM2; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM2_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *instance = TIM2; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; // TIM 2 Channel 2 Direct, Channel 1 Indirect case Pin::PB_3: - *instance = TIM2; - *directChannel = TIM_CHANNEL_2; - *indirectChannel = TIM_CHANNEL_1; - *alternateFunction = GPIO_AF1_TIM2; - *triggerSource = TIM_TS_TI2FP2; - *irqNumber = TIM2_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; - break; + *instance = TIM2; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF1_TIM2; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM2_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; // TIM 15 Channel 1 Direct, Channel 2 Indirect - case Pin::PA_2: //PA2 is UART tx, don't use if using UART - *instance = TIM15; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF9_TIM15; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM1_BRK_TIM15_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + case Pin::PA_2: // PA2 is UART tx, don't use if using UART + *instance = TIM15; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF9_TIM15; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; case Pin::PB_14: - *instance = TIM15; - *directChannel = TIM_CHANNEL_1; - *indirectChannel = TIM_CHANNEL_2; - *alternateFunction = GPIO_AF1_TIM15; - *triggerSource = TIM_TS_TI1FP1; - *irqNumber = TIM1_BRK_TIM15_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; - break; + *instance = TIM15; + *directChannel = TIM_CHANNEL_1; + *indirectChannel = TIM_CHANNEL_2; + *alternateFunction = GPIO_AF1_TIM15; + *triggerSource = TIM_TS_TI1FP1; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_1; + break; // TIM 15 Channel 2 Direct, Channel 1 Indirect - case Pin::PA_3: //PA3 is UART rx, don't use if using UART - *instance = TIM15; - *directChannel = TIM_CHANNEL_2; - *indirectChannel = TIM_CHANNEL_1; - *alternateFunction = GPIO_AF9_TIM15; - *triggerSource = TIM_TS_TI2FP2; - *irqNumber = TIM1_BRK_TIM15_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; - break; + case Pin::PA_3: // PA3 is UART rx, don't use if using UART + *instance = TIM15; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF9_TIM15; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; case Pin::PB_15: - *instance = TIM15; - *directChannel = TIM_CHANNEL_2; - *indirectChannel = TIM_CHANNEL_1; - *alternateFunction = GPIO_AF1_TIM15; - *triggerSource = TIM_TS_TI2FP2; - *irqNumber = TIM1_BRK_TIM15_IRQn; - *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; - break; + *instance = TIM15; + *directChannel = TIM_CHANNEL_2; + *indirectChannel = TIM_CHANNEL_1; + *alternateFunction = GPIO_AF1_TIM15; + *triggerSource = TIM_TS_TI2FP2; + *irqNumber = TIM1_BRK_TIM15_IRQn; + *activeChannel = HAL_TIM_ACTIVE_CHANNEL_2; + break; #endif default: - *instance = NULL; - *directChannel = -1; - *indirectChannel = -1; + *instance = NULL; + *directChannel = -1; + *indirectChannel = -1; *alternateFunction = -1; - *triggerSource = -1; - *irqNumber = (IRQn_Type)-1; - *activeChannel = -1; - + *triggerSource = -1; + *irqNumber = (IRQn_Type) -1; + *activeChannel = -1; } } - - PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { TIM_TypeDef* instance; uint32_t alternateFunction; uint32_t triggerSource; IRQn_Type irqNumber; - getInputInstance(pin, &instance, &directChannel, &indirectChannel, &alternateFunction, &triggerSource, - &irqNumber, &activeChannel); - + getInputInstance(pin, + &instance, + &directChannel, + &indirectChannel, + &alternateFunction, + &triggerSource, + &irqNumber, + &activeChannel); TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_SlaveConfigTypeDef sSlaveConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; - if (instance == TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); } else if (instance == TIM2) { @@ -178,8 +173,7 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { __HAL_RCC_TIM15_CLK_ENABLE(); } - - //initilize timer base + // initilize timer base halTIM.Instance = instance; halTIM.Init.Prescaler = 0; halTIM.Init.CounterMode = TIM_COUNTERMODE_UP; @@ -188,12 +182,12 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { halTIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; HAL_TIM_Base_Init(&halTIM); - //configure clock src + // configure clock src sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&halTIM, &sClockSourceConfig); HAL_TIM_IC_Init(&halTIM); - //slave reset mode, used to measure period + // slave reset mode, used to measure period sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; sSlaveConfig.InputTrigger = triggerSource; sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; @@ -201,14 +195,14 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { sSlaveConfig.TriggerFilter = 0; HAL_TIM_SlaveConfigSynchro(&halTIM, &sSlaveConfig); - //configure direct, rising channel + // configure direct, rising channel sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, directChannel); - //configure indirect, falling channel + // configure indirect, falling channel sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; HAL_TIM_IC_ConfigChannel(&halTIM, &sConfigIC, indirectChannel); @@ -217,16 +211,15 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&halTIM, &sMasterConfig); - //setup GPIO + // setup GPIO GPIO_InitTypeDef gpioInit = {0}; - Pin myPins[] = { pin }; - uint8_t numOfPins = 1; + Pin myPins[] = {pin}; + uint8_t numOfPins = 1; - GPIOf3xx::gpioStateInit(&gpioInit,myPins,numOfPins,GPIO_MODE_AF_PP,GPIO_NOPULL, - GPIO_SPEED_FREQ_LOW,alternateFunction); + GPIOf3xx::gpioStateInit( + &gpioInit, myPins, numOfPins, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, alternateFunction); - - //configure NVIC + // configure NVIC HAL_NVIC_SetPriority(irqNumber, 0, 0); HAL_NVIC_EnableIRQ(irqNumber); // enable interrupt src @@ -236,12 +229,10 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { activePwmInput = this; // Register this instance as active } - TIM_HandleTypeDef* PWM_INPUTf3xx::getHandle() { return &halTIM; } - extern "C" void TIM1_CC_IRQHandler(void) { if (activePwmInput) { HAL_TIM_IRQHandler(activePwmInput->getHandle()); @@ -260,7 +251,6 @@ extern "C" void TIM1_BRK_TIM15_IRQHandler(void) { } } - // Global HAL callback -> forwards to the single active instance extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { if (activePwmInput) { @@ -268,7 +258,6 @@ extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { } } - void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { if (htim->Channel == activeChannel) // If the interrupt is triggered by the active channel { @@ -280,12 +269,11 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { // signal high (time/ period) * 100 = duty cycle as percent dutyCycle = (HAL_TIM_ReadCapturedValue(htim, indirectChannel) * 100) / inputCaptureValue; frequency = SystemCoreClock / inputCaptureValue; - period = inputCaptureValue; + period = inputCaptureValue; } } } - uint32_t PWM_INPUTf3xx::getDutyCycle() { return dutyCycle; } @@ -298,4 +286,4 @@ uint32_t PWM_INPUTf3xx::getFrequency() { return frequency; } -} +} // namespace core::io diff --git a/src/core/io/platform/f4xx/ADCf4xx.cpp b/src/core/io/platform/f4xx/ADCf4xx.cpp index 30f3ebf4..fb86f589 100644 --- a/src/core/io/platform/f4xx/ADCf4xx.cpp +++ b/src/core/io/platform/f4xx/ADCf4xx.cpp @@ -269,7 +269,7 @@ void ADCf4xx::addChannel(uint8_t rank) { default: channelStruct = {}; // sets all values to 0 log::LOGGER.log(log::Logger::LogLevel::ERROR, "INVALID PIN 0x%x!!", pin); - break; // Should never get here + break; // Should never get here } // This checks if the pin being used supports the ADC being used diff --git a/src/core/rtos/tsio/ThreadUART.cpp b/src/core/rtos/tsio/ThreadUART.cpp index d912b7de..58606f9d 100644 --- a/src/core/rtos/tsio/ThreadUART.cpp +++ b/src/core/rtos/tsio/ThreadUART.cpp @@ -70,7 +70,7 @@ void ThreadUART::printf(const char* format, ...) { va_list args; /* Access the variable argument list */ va_start(args, format); /* Tells the args variable to point to the format parameter first */ - char buffer[256]; /* Buffer array to hold the message */ + char buffer[256]; /* Buffer array to hold the message */ vsnprintf(buffer, sizeof(buffer), format, args); /* vsnprint formats the string and stores it in the buffer array */ buffer[255] = '\0'; From 263b711e0141d1c391af634a4c5030b218101445 Mon Sep 17 00:00:00 2001 From: Xander Budge <83941337+XanBu@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:16:11 -0400 Subject: [PATCH 15/22] Update samples/pwm/main.cpp Left over testing change Co-authored-by: Taylor Lineman --- samples/pwm/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/pwm/main.cpp b/samples/pwm/main.cpp index 6d326dd3..c3745e0d 100644 --- a/samples/pwm/main.cpp +++ b/samples/pwm/main.cpp @@ -17,7 +17,7 @@ int main() { // 1000000 microseconds (1 second) period pwm.setPeriod(1000000); // 50 % duty cycle - pwm.setDutyCycle(70); + pwm.setDutyCycle(50); while (1) { time::wait(5000); From 0be73e08397928d621e5a0039e4ef8b43cdc123f Mon Sep 17 00:00:00 2001 From: Xander Budge <83941337+XanBu@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:16:44 -0400 Subject: [PATCH 16/22] Update src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp Removed extra empty line Co-authored-by: Taylor Lineman --- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 4c1bef4d..9c107d4e 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -22,7 +22,6 @@ static PWM_INPUTf3xx* activePwmInput = nullptr; * @param irqNumber IRQ number for NVIC * @param activeChannel HAL enum for which channel will fire the interrupt */ - static void getInputInstance(Pin pin, TIM_TypeDef** instance, uint32_t* directChannel, uint32_t* indirectChannel, uint32_t* alternateFunction, uint32_t* triggerSource, IRQn_Type* irqNumber, uint32_t* activeChannel) { From 73965049d9c43d5d95e9b8d7ac9ecbdf9ff0c879 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 9 Oct 2025 18:24:40 -0400 Subject: [PATCH 17/22] Moved Period, Frequency, and DutyCycle to be local variables in main pwm_input sample --- samples/pwm_input/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 6a1e8c01..cf1abb39 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -11,10 +11,6 @@ namespace io = core::io; namespace time = core::time; -uint32_t Period = 0; // ICValue -uint32_t Frequency = 0; -uint32_t DutyCycle = 0; - int main(void) { // Initialize system core::platform::init(); @@ -24,6 +20,10 @@ int main(void) { uart.printf("Starting PWM input capture\n\r"); + uint32_t Period = 0; // ICValue + uint32_t Frequency = 0; + uint32_t DutyCycle = 0; + io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); while (1) { From 921a336962f0e82b52099f51ddbb38589a9c98e8 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 16 Oct 2025 19:51:50 -0400 Subject: [PATCH 18/22] Changed dutyCycle to be a uint8_t because it is whole percentages. Fixed order of #include directives. --- include/core/io/PWM_INPUT.hpp | 4 ++-- include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp | 6 +++--- samples/pwm_input/main.cpp | 4 ++-- src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWM_INPUT.hpp index 40f070fb..e42a56b0 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWM_INPUT.hpp @@ -26,7 +26,7 @@ class PWM_INPUT { * * @return The duty cycle of the PWM signal being read, as a percentage. */ - virtual uint32_t getDutyCycle() = 0; + virtual uint8_t getDutyCycle() = 0; /** * Get the current period. @@ -46,7 +46,7 @@ class PWM_INPUT { /// The pin PWM input is on Pin pin; /// The duty cycle of the PWM input - uint32_t dutyCycle; + uint8_t dutyCycle; /// The period of the PWM input uint32_t period; /// The frequency of the PWM input diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp index 5eedfb02..74f57b5c 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp @@ -2,11 +2,11 @@ #ifndef EVT_PWM_INPUTF3XX_HPP #define EVT_PWM_INPUTF3XX_HPP -#include - #include + #include #include +#include namespace core::io { @@ -23,7 +23,7 @@ class PWM_INPUTf3xx : public PWM_INPUT { */ PWM_INPUTf3xx(Pin pin); - uint32_t getDutyCycle(); + uint8_t getDutyCycle(); uint32_t getPeriod(); diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index cf1abb39..102a63f1 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -3,9 +3,9 @@ * This sample will measure the duty cycle, frequency, and period of a PWM signal. */ +#include #include #include -#include #include namespace io = core::io; @@ -22,7 +22,7 @@ int main(void) { uint32_t Period = 0; // ICValue uint32_t Frequency = 0; - uint32_t DutyCycle = 0; + uint8_t DutyCycle = 0; io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp index 9c107d4e..344c2d31 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp @@ -273,7 +273,7 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { } } -uint32_t PWM_INPUTf3xx::getDutyCycle() { +uint8_t PWM_INPUTf3xx::getDutyCycle() { return dutyCycle; } From a360bcc1b102a1f62f269c718c9b7f1927d5ff78 Mon Sep 17 00:00:00 2001 From: Xander Budge <83941337+XanBu@users.noreply.github.com> Date: Thu, 16 Oct 2025 19:53:11 -0400 Subject: [PATCH 19/22] Update samples/pwm_input/main.cpp print duty cycle w/ min 2 digits Co-authored-by: Matthew Heller <69865851+mjh9585@users.noreply.github.com> --- samples/pwm_input/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index cf1abb39..819f277c 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -32,7 +32,7 @@ int main(void) { DutyCycle = pwmInput.getDutyCycle(); uart.printf("\n\rPeriod: %d\n\r", Period); uart.printf("\n\rFrequency: %d\n\r", Frequency); - uart.printf("\n\rDuty: %d\n\r", DutyCycle); + uart.printf("\n\rDuty: %2d%%\n\r", DutyCycle); uart.printf("\n\r----------------------------------\n\r"); time::wait(1000); } From f2a2fe047aed7549d8deb0898d5ecb07a87f3568 Mon Sep 17 00:00:00 2001 From: GitHub Build Date: Fri, 17 Oct 2025 00:07:16 +0000 Subject: [PATCH 20/22] Applied Formatting Changes During GitHub Build --- samples/pwm_input/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 0f12c897..0afc3077 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -3,9 +3,9 @@ * This sample will measure the duty cycle, frequency, and period of a PWM signal. */ -#include #include #include +#include #include namespace io = core::io; @@ -22,7 +22,7 @@ int main(void) { uint32_t Period = 0; // ICValue uint32_t Frequency = 0; - uint8_t DutyCycle = 0; + uint8_t DutyCycle = 0; io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); From d91f8e4d6333bc0859b45fe56abbaa11c2acf658 Mon Sep 17 00:00:00 2001 From: Xander B Date: Thu, 16 Oct 2025 20:15:34 -0400 Subject: [PATCH 21/22] Changed names to follow standard naming convention --- CMakeLists.txt | 4 ++-- include/core/io/{PWM_INPUT.hpp => PWMInput.hpp} | 12 ++++++------ .../f3xx/{PWM_INPUTf3xx.hpp => PWMInputf3xx.hpp} | 10 +++++----- include/core/manager.hpp | 12 ++++++------ samples/pwm_input/main.cpp | 6 +++--- src/core/io/{PWM_INPUT.cpp => PWMInput.cpp} | 4 ++-- .../f3xx/{PWM_INPUTf3xx.cpp => PWMInputf3xx.cpp} | 16 ++++++++-------- 7 files changed, 32 insertions(+), 32 deletions(-) rename include/core/io/{PWM_INPUT.hpp => PWMInput.hpp} (84%) rename include/core/io/platform/f3xx/{PWM_INPUTf3xx.hpp => PWMInputf3xx.hpp} (85%) rename src/core/io/{PWM_INPUT.cpp => PWMInput.cpp} (63%) rename src/core/io/platform/f3xx/{PWM_INPUTf3xx.cpp => PWMInputf3xx.cpp} (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 852fb9d6..d098d6aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ target_sources(${PROJECT_NAME} PRIVATE src/core/io/GPIO.cpp src/core/io/I2C.cpp src/core/io/PWM.cpp - src/core/io/PWM_INPUT.cpp + src/core/io/PWMInput.cpp src/core/io/UART.cpp src/core/io/SPI.cpp src/core/io/types/CANMessage.cpp @@ -58,7 +58,7 @@ if(COMPDEFS MATCHES "(.*)STM32F3xx(.*)") src/core/io/platform/f3xx/GPIOf3xx.cpp src/core/io/platform/f3xx/I2Cf3xx.cpp src/core/io/platform/f3xx/PWMf3xx.cpp - src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp + src/core/io/platform/f3xx/PWMInputf3xx.cpp src/core/io/platform/f3xx/UARTf3xx.cpp src/core/io/platform/f3xx/SPIf3xx.cpp src/core/dev/platform/f3xx/IWDGf3xx.cpp diff --git a/include/core/io/PWM_INPUT.hpp b/include/core/io/PWMInput.hpp similarity index 84% rename from include/core/io/PWM_INPUT.hpp rename to include/core/io/PWMInput.hpp index e42a56b0..d1fec2f3 100644 --- a/include/core/io/PWM_INPUT.hpp +++ b/include/core/io/PWMInput.hpp @@ -1,6 +1,6 @@ -#ifndef EVT_PWM_INPUT_HPP -#define EVT_PWM_INPUT_HPP +#ifndef EVT_PWMINPUT_HPP +#define EVT_PWMINPUT_HPP #include @@ -11,15 +11,15 @@ namespace core::io { // at compilation time the decision of which pins should be used. enum class Pin; -class PWM_INPUT { +class PWMInput { public: /** - * Setup the given pin for PWM_INPUT usage. + * Setup the given pin for PWMInput usage. * - * @param[in] pin The pin to setup for PWM_INPUT + * @param[in] pin The pin to setup for PWMInput */ - PWM_INPUT(Pin pin); + PWMInput(Pin pin); /** * Get the current duty cycle. diff --git a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp b/include/core/io/platform/f3xx/PWMInputf3xx.hpp similarity index 85% rename from include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp rename to include/core/io/platform/f3xx/PWMInputf3xx.hpp index 74f57b5c..30d2b320 100644 --- a/include/core/io/platform/f3xx/PWM_INPUTf3xx.hpp +++ b/include/core/io/platform/f3xx/PWMInputf3xx.hpp @@ -1,10 +1,10 @@ -#ifndef EVT_PWM_INPUTF3XX_HPP -#define EVT_PWM_INPUTF3XX_HPP +#ifndef EVT_PWMINPUTF3XX_HPP +#define EVT_PWMINPUTF3XX_HPP #include -#include +#include #include #include @@ -14,14 +14,14 @@ namespace core::io { * PWM input for f3 * Measures the duty cycle, frequency, and period of a PWM signal on a pin */ -class PWM_INPUTf3xx : public PWM_INPUT { +class PWMInputf3xx : public PWMInput { public: /** * Setup the given pin for PWM Input usage. * * @param pin[in] The pin to setup for PWM Input Capture */ - PWM_INPUTf3xx(Pin pin); + PWMInputf3xx(Pin pin); uint8_t getDutyCycle(); diff --git a/include/core/manager.hpp b/include/core/manager.hpp index e78c1341..0c5cca53 100644 --- a/include/core/manager.hpp +++ b/include/core/manager.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -33,7 +33,7 @@ #include #include #include - #include + #include #include #include #include @@ -244,15 +244,15 @@ PWM& getPWM() { #endif /** - * Get an instance of a PWM_INPUT pin. + * Get an instance of a PWMInput pin. * - * @param[in] pin The pin to attach to the PWM_INPUT. + * @param[in] pin The pin to attach to the PWMInput. */ #ifdef PWM_INPUT_SUPPORTED template -PWM_INPUT& getPWM_INPUT() { +PWMInput& getPWM_INPUT() { #ifdef STM32F3xx - static PWM_INPUTf3xx pwm_input(pin); + static PWMInputf3xx pwm_input(pin); return pwm_input; #endif } diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index 0f12c897..c484a253 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -3,9 +3,9 @@ * This sample will measure the duty cycle, frequency, and period of a PWM signal. */ -#include -#include +#include #include +#include #include namespace io = core::io; @@ -24,7 +24,7 @@ int main(void) { uint32_t Frequency = 0; uint8_t DutyCycle = 0; - io::PWM_INPUT& pwmInput = io::getPWM_INPUT(); + io::PWMInput& pwmInput = io::getPWM_INPUT(); while (1) { Period = pwmInput.getPeriod(); diff --git a/src/core/io/PWM_INPUT.cpp b/src/core/io/PWMInput.cpp similarity index 63% rename from src/core/io/PWM_INPUT.cpp rename to src/core/io/PWMInput.cpp index 13d62f8e..5f538f98 100644 --- a/src/core/io/PWM_INPUT.cpp +++ b/src/core/io/PWMInput.cpp @@ -1,8 +1,8 @@ -#include +#include namespace core::io { -PWM_INPUT::PWM_INPUT(Pin pin) { // core::io::Pin pin +PWMInput::PWMInput(Pin pin) { // core::io::Pin pin this->pin = pin; this->dutyCycle = 0; this->period = 0; diff --git a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp b/src/core/io/platform/f3xx/PWMInputf3xx.cpp similarity index 96% rename from src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp rename to src/core/io/platform/f3xx/PWMInputf3xx.cpp index 344c2d31..f55969fd 100644 --- a/src/core/io/platform/f3xx/PWM_INPUTf3xx.cpp +++ b/src/core/io/platform/f3xx/PWMInputf3xx.cpp @@ -1,11 +1,11 @@ #include -#include +#include namespace core::io { // Global pointer to the active instance (one at a time) -static PWM_INPUTf3xx* activePwmInput = nullptr; +static PWMInputf3xx* activePwmInput = nullptr; /** * Get timer instance, direct channel, indirect channel, alternate function, @@ -144,7 +144,7 @@ static void getInputInstance(Pin pin, TIM_TypeDef** instance, uint32_t* directCh } } -PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { +PWMInputf3xx::PWMInputf3xx(Pin pin) : PWMInput(pin) { TIM_TypeDef* instance; uint32_t alternateFunction; uint32_t triggerSource; @@ -228,7 +228,7 @@ PWM_INPUTf3xx::PWM_INPUTf3xx(Pin pin) : PWM_INPUT(pin) { activePwmInput = this; // Register this instance as active } -TIM_HandleTypeDef* PWM_INPUTf3xx::getHandle() { +TIM_HandleTypeDef* PWMInputf3xx::getHandle() { return &halTIM; } @@ -257,7 +257,7 @@ extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { } } -void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { +void PWMInputf3xx::handleCapture(TIM_HandleTypeDef* htim) { if (htim->Channel == activeChannel) // If the interrupt is triggered by the active channel { // Read the IC value (period) @@ -273,15 +273,15 @@ void PWM_INPUTf3xx::handleCapture(TIM_HandleTypeDef* htim) { } } -uint8_t PWM_INPUTf3xx::getDutyCycle() { +uint8_t PWMInputf3xx::getDutyCycle() { return dutyCycle; } -uint32_t PWM_INPUTf3xx::getPeriod() { +uint32_t PWMInputf3xx::getPeriod() { return period; } -uint32_t PWM_INPUTf3xx::getFrequency() { +uint32_t PWMInputf3xx::getFrequency() { return frequency; } From d698e7230d07cd5b756c9a72d3536d2fd80ee8cb Mon Sep 17 00:00:00 2001 From: GitHub Build Date: Fri, 17 Oct 2025 00:22:55 +0000 Subject: [PATCH 22/22] Applied Formatting Changes During GitHub Build --- samples/pwm_input/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/pwm_input/main.cpp b/samples/pwm_input/main.cpp index a37f4dff..35ac7805 100644 --- a/samples/pwm_input/main.cpp +++ b/samples/pwm_input/main.cpp @@ -3,7 +3,6 @@ * This sample will measure the duty cycle, frequency, and period of a PWM signal. */ - #include #include #include