diff --git a/experimenting/Core/Inc/comms.h b/experimenting/Core/Inc/comms.h new file mode 100644 index 0000000..9e20db6 --- /dev/null +++ b/experimenting/Core/Inc/comms.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file : comms.h + * @brief : Header for comms.c file. + * This file contains the display (serial, LCD, etc) defines + * of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 The Digital Mermaid + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef __COMMS_H__ +#define __COMMS_H__ + +#include + +/** + * @brief Stores the switch settings of the system for display. + * @param main: main switch (LCD display) + * @param throttleStop: throttle stop switch + * @param speed10kwHigh High speed switch for 10kw motor + * @param speed10kwLow Low speed switch for 10kw motor + * @param speed5kwHigh High speed switch for 5kw motor + * @param speed5kwLow Low speed switch for 5kw motor + * @retval None + */ +void lcdSetGlobalSwitches(uint8_t main, uint8_t throttleStop, uint8_t speed10kwHigh, uint8_t speed10kwLow, uint8_t speed5kwHigh, uint8_t speed5kwLow); + +/** + * @brief Prints data to serial, LCDs, LED displays, etc. + * @retval None + * @note All but serial are disabled if the main switch is off. + */ +void commsPrint(); + +/** + * @brief Initialize Comms; LCD, serial, LED displays, etc. + * @retval None +*/ +void commsInit(); + +#endif diff --git a/experimenting/Core/Inc/config.h b/experimenting/Core/Inc/config.h new file mode 100644 index 0000000..4091481 --- /dev/null +++ b/experimenting/Core/Inc/config.h @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * @file : config.h + * @brief : Header for config.c file. + * This file contains global configs for mhelm + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 The Digital Mermaid. + * All rights reserved. + * + * This software is licensed under the GPL v3, the terms can be found in the + * LICENSE file in the root directory of this software component. + * + ****************************************************************************** + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#define MAJOR_VERSION 0 +#define MINOR_VERSION 1 +#define ADC_NUM_CHANS 3 + +// interrupt prios +#define INT_PRIO_SYSTICK 0 +#define INT_PRIO_USB 4 +#define INT_PRIO_SPI 5 +#define INT_PRIO_RT_TASK 6 +#define INT_PRIO_ADC 7 + +#endif diff --git a/experimenting/Core/Inc/main.h b/experimenting/Core/Inc/main.h new file mode 100644 index 0000000..7f19e3b --- /dev/null +++ b/experimenting/Core/Inc/main.h @@ -0,0 +1,130 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +// Define pins +#define B1_Pin GPIO_PIN_13 +#define B1_GPIO_Port GPIOC +#define THROTTLE_STBD_POT_Pin GPIO_PIN_0 +#define THROTTLE_STBD_POT_GPIO_Port GPIOA +#define REGEN_POT_Pin GPIO_PIN_1 +#define REGEN_POT_GPIO_Port GPIOA +#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 M5KW_BRAKE_OUT_Pin GPIO_PIN_4 +#define M5KW_BRAKE_OUT_GPIO_Port GPIOF +#define M5KW_SPEED_LOW_OUT_Pin GPIO_PIN_5 +#define M5KW_SPEED_LOW_OUT_GPIO_Port GPIOF +#define THROTTLE_PORT_POT_Pin GPIO_PIN_4 +#define THROTTLE_PORT_POT_GPIO_Port GPIOA +#define LD2_Pin GPIO_PIN_5 +#define LD2_GPIO_Port GPIOA +#define LCD_BL_RED_Pin GPIO_PIN_6 +#define LCD_BL_RED_GPIO_Port GPIOA +#define LCD_BL_GREEN_Pin GPIO_PIN_7 +#define LCD_BL_GREEN_GPIO_Port GPIOA +#define M5KW_SPEED_HIGH_OUT_Pin GPIO_PIN_4 +#define M5KW_SPEED_HIGH_OUT_GPIO_Port GPIOC +#define LCD_BL_BLUE_Pin GPIO_PIN_0 +#define LCD_BL_BLUE_GPIO_Port GPIOB +#define PANEL_CS_Pin GPIO_PIN_10 +#define PANEL_CS_GPIO_Port GPIOB +#define LCD_SDA_Pin GPIO_PIN_11 +#define LCD_SDA_GPIO_Port GPIOB +#define M10KW_BRAKE_OUT_Pin GPIO_PIN_13 +#define M10KW_BRAKE_OUT_GPIO_Port GPIOB +#define M10KW_SPEED_LOW_OUT_Pin GPIO_PIN_14 +#define M10KW_SPEED_LOW_OUT_GPIO_Port GPIOB +#define M10KW_SPEED_HIGH_OUT_Pin GPIO_PIN_15 +#define M10KW_SPEED_HIGH_OUT_GPIO_Port GPIOB +#define LCD_SCL_Pin GPIO_PIN_6 +#define LCD_SCL_GPIO_Port GPIOF +#define ESTOP_SW_IN_Pin GPIO_PIN_7 +#define ESTOP_SW_IN_GPIO_Port GPIOF +#define TCK_Pin GPIO_PIN_14 +#define TCK_GPIO_Port GPIOA +#define BACKUP_KEY_SW_IN_Pin GPIO_PIN_15 +#define BACKUP_KEY_SW_IN_GPIO_Port GPIOA +#define M5KW_REGEN_DAC_A0_Pin GPIO_PIN_10 +#define M5KW_REGEN_DAC_A0_GPIO_Port GPIOC +#define M10KW_REGEN_DAC_A0_Pin GPIO_PIN_11 +#define M10KW_REGEN_DAC_A0_GPIO_Port GPIOC +#define M5KW_THROTTLE_DAC_A0_Pin GPIO_PIN_12 +#define M5KW_THROTTLE_DAC_A0_GPIO_Port GPIOC +#define M10KW_THROTTLE_DAC_A0_Pin GPIO_PIN_2 +#define M10KW_THROTTLE_DAC_A0_GPIO_Port GPIOD +#define DAC_SDA_Pin GPIO_PIN_7 +#define DAC_SDA_GPIO_Port GPIOB +#define DAC_SCL_Pin GPIO_PIN_8 +#define DAC_SCL_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ +// main timer task +void main_timer_task(void); + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/experimenting/Core/Inc/panel.h b/experimenting/Core/Inc/panel.h new file mode 100644 index 0000000..01155eb --- /dev/null +++ b/experimenting/Core/Inc/panel.h @@ -0,0 +1,30 @@ +/* + * Panel Interface Code + * + * Copyright 2024: Digital Mermaid + * Written by: digimer + * + */ +#ifndef PANEL_H +#define PANEL_H + +#include + +// settings +#define PANEL_SPI_BUFLEN 2 + +// init the panel +void panel_init(void); + +// run the panel timer task +void panel_timer_task(void); + +typedef struct panel_state { + uint8_t spi_tx_buf[PANEL_SPI_BUFLEN]; + uint8_t spi_rx_buf[PANEL_SPI_BUFLEN]; +}; + +// panel state +extern struct panel_state panstate; + +#endif \ No newline at end of file diff --git a/experimenting/Core/Inc/stm32f0xx_hal_conf.h b/experimenting/Core/Inc/stm32f0xx_hal_conf.h new file mode 100644 index 0000000..392f936 --- /dev/null +++ b/experimenting/Core/Inc/stm32f0xx_hal_conf.h @@ -0,0 +1,322 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + #define HAL_ADC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined (HSI14_VALUE) +#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)40000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSI) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 0 +#define DATA_CACHE_ENABLE 0 +#define USE_SPI_CRC 0U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ + diff --git a/experimenting/Core/Inc/stm32f0xx_it.h b/experimenting/Core/Inc/stm32f0xx_it.h new file mode 100644 index 0000000..45aa8a0 --- /dev/null +++ b/experimenting/Core/Inc/stm32f0xx_it.h @@ -0,0 +1,68 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_IT_H +#define __STM32F0xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void SVC_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void DMA1_Channel1_IRQHandler(void); +void DMA1_Channel2_3_IRQHandler(void); +void ADC1_IRQHandler(void); +void TIM1_BRK_UP_TRG_COM_IRQHandler(void); +void TIM1_CC_IRQHandler(void); +void SPI1_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_IT_H */ diff --git a/experimenting/Core/Src/comms.c b/experimenting/Core/Src/comms.c new file mode 100644 index 0000000..bc9a8e2 --- /dev/null +++ b/experimenting/Core/Src/comms.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file : comms.c + * @brief : Code for displaying data on the LCD screens, serial + * output, LED displays, etc. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 The Digital Mermaid. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** +**/ +#include +#include + +#include "comms.h" +#include "panel.h" +#include "main.h" + +// This struct contains all the data that is required for the output +// If something of that is DEBUG only I'd mask it for the release version to +// safe some memory It's packed to keep its size small. +typedef struct { + // Switches + uint8_t mainSwitch; + uint8_t throttleStopSwitch; + uint8_t speed10kwHighSwitch; + uint8_t speed10kwLowSwitch; + uint8_t speed5kwHighSwitch; + uint8_t speed5kwLowSwitch; + uint8_t motorSelect; + + // Throttle + uint8_t throttlePortSelect; + uint8_t throttleStarboardSelect; + + uint16_t throttleValueRaw; + uint16_t throttleValuePerMille; + uint16_t throttleValuePerMilleSmooth; + uint16_t throttleValueDac; + + // Regen + uint16_t regenValueRaw; + uint16_t regenValuePerMille; + uint16_t regenValuePerMilleSmooth; + uint16_t regenValueDac; + +} StatusData_t; + +// panel state +struct panel_state panstate; + +static UART_HandleTypeDef huart2; +static StatusData_t status; + +/** + * @brief Get the helm switch positions. + * @param None + * @retval None + */ +void lcdSetGlobalSwitches(uint8_t main, uint8_t throttleStop, uint8_t speed10kwHigh, uint8_t speed10kwLow, uint8_t speed5kwHigh, uint8_t speed5kwLow) { + status.mainSwitch = main; + status.throttleStopSwitch = throttleStop; + status.speed10kwHighSwitch = speed10kwHigh; + status.speed10kwLowSwitch = speed10kwLow; + status.speed5kwHighSwitch = speed5kwHigh; + status.speed5kwLowSwitch = speed5kwLow; +} + +/** + * @brief Prepares the data to display to various outputs; Serial, LCDs, LEDs, + * etc. + * @param None + * @retval None + */ +void commsPrint() { + static uint8_t counter = 0; + char buffer[256]; + + uint8_t switchA = panstate.spi_rx_buf[0]; + uint8_t switchB = panstate.spi_rx_buf[1]; + + // Test output + //sprintf(buffer, "%d - Foo\n\r", counter); +// sprintf(buffer, "%d - switches A/B: [%d]/[%d], \n\r", counter, switchA, switchB); + sprintf(buffer, "%d - switches A/B: [%02x]/[%02x], \n\r", counter, switchA, switchB); +// HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); // Sending in normal mode + + if(switchA & 0x01) { + strcat(buffer, " - page up"); + } + else if(switchA & 0x02) { + strcat(buffer, " - page down"); + } + + if(switchA & 0x04) { + + } + else if(switchA & 0x08) { + + } + + HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), 1000); // Sending in normal mode + counter++; +} + +/** + * @brief USART2 Initialization Function + * @param None + * @retval None + */ +static void MX_USART2_UART_Init(void) { + + /* USER CODE BEGIN USART2_Init 0 */ + + /* USER CODE END USART2_Init 0 */ + + /* USER CODE BEGIN USART2_Init 1 */ + + /* USER CODE END USART2_Init 1 */ + huart2.Instance = USART2; + huart2.Init.BaudRate = 38400; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + if (HAL_UART_Init(&huart2) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN USART2_Init 2 */ + + /* USER CODE END USART2_Init 2 */ +} + +void commsInit() { + // Ground the red pin, set high the green and blue pins + //HAL_GPIO_WritePin(LCD1_BL_RED_GPIO_Port, LCD1_BL_RED_Pin, GPIO_PIN_RESET); + //HAL_GPIO_WritePin(LCD1_BL_GREEN_GPIO_Port, LCD1_BL_GREEN_Pin, GPIO_PIN_SET); + //HAL_GPIO_WritePin(LCD1_BL_BLUE_GPIO_Port, LCD1_BL_BLUE_Pin, GPIO_PIN_SET); + //memset(&status, 0, sizeof(status)); + + MX_USART2_UART_Init(); + + //nd_lcd_init(); +} diff --git a/experimenting/Core/Src/main.c b/experimenting/Core/Src/main.c new file mode 100644 index 0000000..0c9c8a4 --- /dev/null +++ b/experimenting/Core/Src/main.c @@ -0,0 +1,712 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "config.h" +#include "panel.h" +#include "stm32f0xx_hal.h" +#include "comms.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +ADC_HandleTypeDef hadc; +DMA_HandleTypeDef hdma_adc; + +I2C_HandleTypeDef hi2c1; +I2C_HandleTypeDef hi2c2; + +SPI_HandleTypeDef hspi1; +DMA_HandleTypeDef hdma_spi1_rx; +DMA_HandleTypeDef hdma_spi1_tx; + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim3; + +UART_HandleTypeDef huart2; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); +static void MX_SPI1_Init(void); +static void MX_ADC_Init(void); +static void MX_I2C1_Init(void); +static void MX_I2C2_Init(void); +static void MX_TIM1_Init(void); +static void MX_TIM3_Init(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + MX_SPI1_Init(); + //MX_ADC_Init(); + //MX_I2C1_Init(); + //MX_I2C2_Init(); + MX_TIM1_Init(); + MX_TIM3_Init(); + /* USER CODE BEGIN 2 */ + panel_init(); + + // start timers + HAL_TIM_Base_Start_IT(&htim1); + + /* USER CODE END 2 */ + commsInit(); + + // uint8_t count = 0; + uint8_t mainSwitchValue = 0; // This turns the helm displays on (LEDs, etc, + // does NOT disable throttle controls) + uint8_t speed10kwHighSwitchValue = 0; // 0 = Off, 1 = Selected (inverted at GPIO read) + uint8_t speed10kwLowSwitchValue = 0; // 0 = Off, 1 = Selected (inverted at GPIO read) + uint8_t speed5kwHighSwitchValue = 0; // 0 = Off, 1 = Selected (inverted at GPIO read) + uint8_t speed5kwLowSwitchValue = 0; // 0 = Off, 1 = Selected (inverted at GPIO read) + uint8_t throttleStopSwitchValue = 0; // 0 = Run, 1 = Stop - This is the E-Stop + uint8_t motorSwitch = 0; // 0 = 5kw, 1 = 10kw + + uint16_t throttlePerMilleValue = 500; + uint16_t regenPerMilleValue = 500; + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + // Read the switches from the + mainSwitchValue = 0; + + lcdSetGlobalSwitches(mainSwitchValue, throttleStopSwitchValue, speed10kwHighSwitchValue, speed10kwLowSwitchValue, speed5kwHighSwitchValue, speed5kwLowSwitchValue); + commsPrint(); + HAL_Delay(250); + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +// main timer task +void main_timer_task(void) { +/* + static uint8_t tx_buf[2]; + static uint8_t rx_buf[2]; + static int count = 0; + + tx_buf[0] = count >> 6; + tx_buf[1] = 0x44; + count ++; + + HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); + + // start the transfer + if(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY) { + return; + } + HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)tx_buf, (uint8_t *)rx_buf, 1); +*/ + panel_timer_task(); +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14 + |RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI14State = RCC_HSI14_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.HSI14CalibrationValue = 16; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; + RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1; + PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief ADC Initialization Function + * @param None + * @retval None + */ +static void MX_ADC_Init(void) +{ + + /* USER CODE BEGIN ADC_Init 0 */ + + /* USER CODE END ADC_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC_Init 1 */ + + /* USER CODE END ADC_Init 1 */ + + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + hadc.Instance = ADC1; + hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; + hadc.Init.Resolution = ADC_RESOLUTION_12B; + hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; + hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + hadc.Init.LowPowerAutoWait = DISABLE; + hadc.Init.LowPowerAutoPowerOff = DISABLE; + hadc.Init.ContinuousConvMode = DISABLE; + hadc.Init.DiscontinuousConvMode = DISABLE; + hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc.Init.DMAContinuousRequests = DISABLE; + hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED; + if (HAL_ADC_Init(&hadc) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel to be converted. + */ + sConfig.Channel = ADC_CHANNEL_0; + sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; + sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel to be converted. + */ + sConfig.Channel = ADC_CHANNEL_1; + if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel to be converted. + */ + sConfig.Channel = ADC_CHANNEL_4; + if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC_Init 2 */ + + /* USER CODE END ADC_Init 2 */ + +} + +/** + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ +static void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.Timing = 0x2000090E; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Analogue filter + */ + if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Digital filter + */ + if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +/** + * @brief I2C2 Initialization Function + * @param None + * @retval None + */ +static void MX_I2C2_Init(void) +{ + + /* USER CODE BEGIN I2C2_Init 0 */ + + /* USER CODE END I2C2_Init 0 */ + + /* USER CODE BEGIN I2C2_Init 1 */ + + /* USER CODE END I2C2_Init 1 */ + hi2c2.Instance = I2C2; + hi2c2.Init.Timing = 0x20303E5D; + hi2c2.Init.OwnAddress1 = 0; + hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c2.Init.OwnAddress2 = 0; + hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK; + hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c2) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Analogue filter + */ + if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Digital filter + */ + if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C2_Init 2 */ + + /* USER CODE END I2C2_Init 2 */ + +} + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 7; + hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} + +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 8; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 5333; // 500 Hz + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + +} + +/** + * @brief TIM3 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM3_Init(void) +{ + + /* USER CODE BEGIN TIM3_Init 0 */ + + /* USER CODE END TIM3_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM3_Init 1 */ + + /* USER CODE END TIM3_Init 1 */ + htim3.Instance = TIM3; + htim3.Init.Prescaler = 0; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + htim3.Init.Period = 65535; + htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim3) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM3_Init 2 */ + + /* USER CODE END TIM3_Init 2 */ + HAL_TIM_MspPostInit(&htim3); + +} + +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel1_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); + /* DMA1_Channel2_3_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; +/* USER CODE BEGIN MX_GPIO_Init_1 */ +/* 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(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOF, M5KW_BRAKE_OUT_Pin|M5KW_SPEED_LOW_OUT_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOC, M5KW_SPEED_HIGH_OUT_Pin|M5KW_REGEN_DAC_A0_Pin|M10KW_REGEN_DAC_A0_Pin|M5KW_THROTTLE_DAC_A0_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOB, PANEL_CS_Pin|M10KW_BRAKE_OUT_Pin|M10KW_SPEED_LOW_OUT_Pin|M10KW_SPEED_HIGH_OUT_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(M10KW_THROTTLE_DAC_A0_GPIO_Port, M10KW_THROTTLE_DAC_A0_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 pins : M5KW_BRAKE_OUT_Pin M5KW_SPEED_LOW_OUT_Pin */ + GPIO_InitStruct.Pin = M5KW_BRAKE_OUT_Pin|M5KW_SPEED_LOW_OUT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOF, &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); + + /*Configure GPIO pins : M5KW_SPEED_HIGH_OUT_Pin M5KW_REGEN_DAC_A0_Pin M10KW_REGEN_DAC_A0_Pin M5KW_THROTTLE_DAC_A0_Pin */ + GPIO_InitStruct.Pin = M5KW_SPEED_HIGH_OUT_Pin|M5KW_REGEN_DAC_A0_Pin|M10KW_REGEN_DAC_A0_Pin|M5KW_THROTTLE_DAC_A0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pins : PANEL_CS_Pin M10KW_BRAKE_OUT_Pin M10KW_SPEED_LOW_OUT_Pin M10KW_SPEED_HIGH_OUT_Pin */ + GPIO_InitStruct.Pin = PANEL_CS_Pin|M10KW_BRAKE_OUT_Pin|M10KW_SPEED_LOW_OUT_Pin|M10KW_SPEED_HIGH_OUT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pin : ESTOP_SW_IN_Pin */ + GPIO_InitStruct.Pin = ESTOP_SW_IN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(ESTOP_SW_IN_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : BACKUP_KEY_SW_IN_Pin */ + GPIO_InitStruct.Pin = BACKUP_KEY_SW_IN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(BACKUP_KEY_SW_IN_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : M10KW_THROTTLE_DAC_A0_Pin */ + GPIO_InitStruct.Pin = M10KW_THROTTLE_DAC_A0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(M10KW_THROTTLE_DAC_A0_GPIO_Port, &GPIO_InitStruct); + +/* USER CODE BEGIN MX_GPIO_Init_2 */ +/* USER CODE END MX_GPIO_Init_2 */ +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM1 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM1) { + main_timer_task(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +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) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/experimenting/Core/Src/panel.c b/experimenting/Core/Src/panel.c new file mode 100644 index 0000000..f2e91f0 --- /dev/null +++ b/experimenting/Core/Src/panel.c @@ -0,0 +1,65 @@ +/* + * Panel Interface Code + * + * Copyright 2024: Digital Mermaid + * Written by: digimer + * + */ +#include "panel.h" +#include "main.h" +#include "config.h" +#include "stm32f0xx_hal.h" +#include + +// hardware handles +extern SPI_HandleTypeDef hspi1; +uint8_t panel_rx_buf[2]; + +// init the panel +void panel_init(void) { + int i; + for(i = 0; i < PANEL_SPI_BUFLEN; i ++) { + panstate.spi_tx_buf[i] = 0x00; + panstate.spi_rx_buf[i] = 0xff; + } +} + +// run the panel timer task +void panel_timer_task(void) { + static int count = 0; + + panstate.spi_tx_buf[1] = count >> 8; + //panstate.spi_tx_buf[0] = count >> 6; + //panstate.spi_tx_buf[1] = count >> 6; + // tx_buf[1] = 0x44; +/* + int i; + for(i = 0; i < PANEL_SPI_BUFLEN; i ++) { + panstate.spi_tx_buf[i] = 0x02; + panstate.spi_rx_buf[i] = 0x00; + }*/ + count ++; + + // XXX debug + HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); + + // start the SPI transfer + if(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY) { + return; + } + HAL_GPIO_WritePin(PANEL_CS_GPIO_Port, PANEL_CS_Pin, 1); + HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)panstate.spi_tx_buf, + (uint8_t *)panstate.spi_rx_buf, PANEL_SPI_BUFLEN); +// HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)panstate.spi_tx_buf, +// (uint8_t *)panel_rx_buf, PANEL_SPI_BUFLEN); +} + +// +// callbacks +// +// handle TX/RX transfer complete +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { + if(hspi == &hspi1) { + HAL_GPIO_WritePin(PANEL_CS_GPIO_Port, PANEL_CS_Pin, 0); + } +} \ No newline at end of file diff --git a/experimenting/Core/Src/stm32f0xx_hal_msp.c b/experimenting/Core/Src/stm32f0xx_hal_msp.c new file mode 100644 index 0000000..fa14636 --- /dev/null +++ b/experimenting/Core/Src/stm32f0xx_hal_msp.c @@ -0,0 +1,582 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_hal.h" +#include + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_adc; +extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief ADC MSP Initialization +* This function configures the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**ADC GPIO Configuration + PA0 ------> ADC_IN0 + PA1 ------> ADC_IN1 + PA4 ------> ADC_IN4 + */ + GPIO_InitStruct.Pin = THROTTLE_STBD_POT_Pin|REGEN_POT_Pin|THROTTLE_PORT_POT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* ADC1 DMA Init */ + /* ADC Init */ + hdma_adc.Instance = DMA1_Channel1; + hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_adc.Init.Mode = DMA_CIRCULAR; + hdma_adc.Init.Priority = DMA_PRIORITY_MEDIUM; + if (HAL_DMA_Init(&hdma_adc) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc); + + /* ADC1 interrupt Init */ + HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(ADC1_IRQn); + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } + +} + +/** +* @brief ADC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) +{ + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC GPIO Configuration + PA0 ------> ADC_IN0 + PA1 ------> ADC_IN1 + PA4 ------> ADC_IN4 + */ + HAL_GPIO_DeInit(GPIOA, THROTTLE_STBD_POT_Pin|REGEN_POT_Pin|THROTTLE_PORT_POT_Pin); + + /* ADC1 DMA DeInit */ + HAL_DMA_DeInit(hadc->DMA_Handle); + + /* ADC1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(ADC1_IRQn); + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } + +} + +/** +* @brief I2C MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB7 ------> I2C1_SDA + PB8 ------> I2C1_SCL + */ + GPIO_InitStruct.Pin = DAC_SDA_Pin|DAC_SCL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } + else if(hi2c->Instance==I2C2) + { + /* USER CODE BEGIN I2C2_MspInit 0 */ + + /* USER CODE END I2C2_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + /**I2C2 GPIO Configuration + PB11 ------> I2C2_SDA + PF6 ------> I2C2_SCL + */ + GPIO_InitStruct.Pin = LCD_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_I2C2; + HAL_GPIO_Init(LCD_SDA_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LCD_SCL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LCD_SCL_GPIO_Port, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C2_CLK_ENABLE(); + /* USER CODE BEGIN I2C2_MspInit 1 */ + + /* USER CODE END I2C2_MspInit 1 */ + } + +} + +/** +* @brief I2C MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) +{ + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB7 ------> I2C1_SDA + PB8 ------> I2C1_SCL + */ + HAL_GPIO_DeInit(DAC_SDA_GPIO_Port, DAC_SDA_Pin); + + HAL_GPIO_DeInit(DAC_SCL_GPIO_Port, DAC_SCL_Pin); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } + else if(hi2c->Instance==I2C2) + { + /* USER CODE BEGIN I2C2_MspDeInit 0 */ + + /* USER CODE END I2C2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C2_CLK_DISABLE(); + + /**I2C2 GPIO Configuration + PB11 ------> I2C2_SDA + PF6 ------> I2C2_SCL + */ + HAL_GPIO_DeInit(LCD_SDA_GPIO_Port, LCD_SDA_Pin); + + HAL_GPIO_DeInit(LCD_SCL_GPIO_Port, LCD_SCL_Pin); + + /* USER CODE BEGIN I2C2_MspDeInit 1 */ + + /* USER CODE END I2C2_MspDeInit 1 */ + } + +} + +/** +* @brief SPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF0_SPI1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* SPI1 DMA Init */ + /* SPI1_RX Init */ + hdma_spi1_rx.Instance = DMA1_Channel2; + hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_spi1_rx.Init.Mode = DMA_NORMAL; + hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx); + + /* SPI1_TX Init */ + hdma_spi1_tx.Instance = DMA1_Channel3; + hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_spi1_tx.Init.Mode = DMA_NORMAL; + hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx); + + /* SPI1 interrupt Init */ + HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(SPI1_IRQn); + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } + +} + +/** +* @brief SPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) +{ + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5); + + /* SPI1 DMA DeInit */ + HAL_DMA_DeInit(hspi->hdmarx); + HAL_DMA_DeInit(hspi->hdmatx); + + /* SPI1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(SPI1_IRQn); + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } + +} + +/** +* @brief TIM_Base MSP Initialization +* This function configures the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspInit 0 */ + + /* USER CODE END TIM1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM1_CLK_ENABLE(); + /* TIM1 interrupt Init */ + HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, INT_PRIO_RT_TASK, 0); + HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); + HAL_NVIC_SetPriority(TIM1_CC_IRQn, INT_PRIO_RT_TASK, 0); + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + /* USER CODE BEGIN TIM1_MspInit 1 */ + + /* USER CODE END TIM1_MspInit 1 */ + } + else if(htim_base->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspInit 0 */ + + /* USER CODE END TIM3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM3_CLK_ENABLE(); + /* USER CODE BEGIN TIM3_MspInit 1 */ + + /* USER CODE END TIM3_MspInit 1 */ + } + +} + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspPostInit 0 */ + + /* USER CODE END TIM3_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**TIM3 GPIO Configuration + PA6 ------> TIM3_CH1 + PA7 ------> TIM3_CH2 + PB0 ------> TIM3_CH3 + */ + GPIO_InitStruct.Pin = LCD_BL_RED_Pin|LCD_BL_GREEN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LCD_BL_BLUE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; + HAL_GPIO_Init(LCD_BL_BLUE_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM3_MspPostInit 1 */ + + /* USER CODE END TIM3_MspPostInit 1 */ + } + +} +/** +* @brief TIM_Base MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspDeInit 0 */ + + /* USER CODE END TIM1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM1_CLK_DISABLE(); + + /* TIM1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); + HAL_NVIC_DisableIRQ(TIM1_CC_IRQn); + /* USER CODE BEGIN TIM1_MspDeInit 1 */ + + /* USER CODE END TIM1_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspDeInit 0 */ + + /* USER CODE END TIM3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM3_CLK_DISABLE(); + /* USER CODE BEGIN TIM3_MspDeInit 1 */ + + /* USER CODE END TIM3_MspDeInit 1 */ + } + +} + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_USART2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + +} + +/** +* @brief UART MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, USART_TX_Pin|USART_RX_Pin); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/experimenting/Core/Src/stm32f0xx_it.c b/experimenting/Core/Src/stm32f0xx_it.c new file mode 100644 index 0000000..c19acac --- /dev/null +++ b/experimenting/Core/Src/stm32f0xx_it.c @@ -0,0 +1,235 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern DMA_HandleTypeDef hdma_adc; +extern ADC_HandleTypeDef hadc; +extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; +extern SPI_HandleTypeDef hspi1; +extern TIM_HandleTypeDef htim1; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M0 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVC_IRQn 0 */ + + /* USER CODE END SVC_IRQn 0 */ + /* USER CODE BEGIN SVC_IRQn 1 */ + + /* USER CODE END SVC_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F0xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f0xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles DMA1 channel 1 interrupt. + */ +void DMA1_Channel1_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */ + + /* USER CODE END DMA1_Channel1_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_adc); + /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */ + + /* USER CODE END DMA1_Channel1_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 channel 2 and 3 interrupts. + */ +void DMA1_Channel2_3_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */ + + /* USER CODE END DMA1_Channel2_3_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_rx); + HAL_DMA_IRQHandler(&hdma_spi1_tx); + /* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */ + + /* USER CODE END DMA1_Channel2_3_IRQn 1 */ +} + +/** + * @brief This function handles ADC global interrupt. + */ +void ADC1_IRQHandler(void) +{ + /* USER CODE BEGIN ADC1_IRQn 0 */ + + /* USER CODE END ADC1_IRQn 0 */ + HAL_ADC_IRQHandler(&hadc); + /* USER CODE BEGIN ADC1_IRQn 1 */ + + /* USER CODE END ADC1_IRQn 1 */ +} + +/** + * @brief This function handles TIM1 break, update, trigger and commutation interrupts. + */ +void TIM1_BRK_UP_TRG_COM_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_BRK_UP_TRG_COM_IRQn 0 */ + + /* USER CODE END TIM1_BRK_UP_TRG_COM_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_BRK_UP_TRG_COM_IRQn 1 */ + + /* USER CODE END TIM1_BRK_UP_TRG_COM_IRQn 1 */ +} + +/** + * @brief This function handles TIM1 capture compare interrupt. + */ +void TIM1_CC_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_CC_IRQn 0 */ + + /* USER CODE END TIM1_CC_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_CC_IRQn 1 */ + + /* USER CODE END TIM1_CC_IRQn 1 */ +} + +/** + * @brief This function handles SPI1 global interrupt. + */ +void SPI1_IRQHandler(void) +{ + /* USER CODE BEGIN SPI1_IRQn 0 */ + + /* USER CODE END SPI1_IRQn 0 */ + HAL_SPI_IRQHandler(&hspi1); + /* USER CODE BEGIN SPI1_IRQn 1 */ + + /* USER CODE END SPI1_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/experimenting/Core/Src/system_stm32f0xx.c b/experimenting/Core/Src/system_stm32f0xx.c new file mode 100644 index 0000000..50a4beb --- /dev/null +++ b/experimenting/Core/Src/system_stm32f0xx.c @@ -0,0 +1,249 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f0xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** @addtogroup STM32F0xx_System_Private_Includes + * @{ + */ + +#include "stm32f0xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI48_VALUE */ +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 8000000; + +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* NOTE :SystemInit(): This function is called at startup just after reset and + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, PLL Multiplier + and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * - If SYSCLK source is HSI48, SystemCoreClock will contain the HSI48_VALUE(***) + * + * (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * (***) HSI48_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value + * 48 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + pllmull = ( pllmull >> 18) + 2; + predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; + + if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) + { + /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ + SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull; + } +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) + { + /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */ + SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull; + } +#endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */ + else + { +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \ + || defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \ + || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ + SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull; +#else + /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || + STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || + STM32F091xC || STM32F098xx || STM32F030xC */ + } + break; + default: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/lights/lights.c b/lights/lights.c new file mode 100644 index 0000000..4f526c2 --- /dev/null +++ b/lights/lights.c @@ -0,0 +1,108 @@ +// Takes a switch number, and 'on' or 'off', to control a light on the relay +// board. +// +// Based on 'blink.c'; +// Author: Mike McCauley (mikem@open.com.au) +// Copyright (C) 2011 Mike McCauley +// +// Requires https://www.airspayce.com/mikem/bcm2835/ +// - Tested on the Raspberry Pi 4b +// +// Written by Madison Kelly, digital.mermaid@gmail.com +// Mar. 22, 2025 +// +// v0.1 + +#include +#include +#include + +// Map switches to GPIO pins +#define SW1 RPI_V2_GPIO_P1_11 +#define SW2 RPI_V2_GPIO_P1_13 +#define SW3 RPI_V2_GPIO_P1_15 +#define SW4 RPI_V2_GPIO_P1_12 + +// The relay's normally opened outputs are closed on LOW (and vice versa) +int main(int argc, char **argv) +{ + // If you call this, it will not actually access the GPIO + // Use for testing + //bcm2835_set_debug(1); + + if (!bcm2835_init()) + return 1; + + // Make sure we've got a switch number. + if (!argv[1] || !argv[2]) { + printf("Usage: [%s ]. Switch is 1 ~ 4.\n", argv[0]); + return 1; + } + char *endptr; + long int sw = strtol(argv[1], &endptr, 10); + if (endptr == argv[1]) { + printf("The switch number was not specified or was not a digit.\n"); + printf("Usage: [%s ]. Switch is 1 ~ 4.\n", argv[0]); + return 1; + } else if (*endptr != '\0') { + printf("The switch: [%c] must be an integer.\n", *endptr); + printf("Usage: [%s ]. Switch is 1 ~ 4.\n", argv[0]); + return 1; + } else { + printf("Working on switch: [%ld]\n", sw); + } + + if (sw < 1 || sw > 4) { + printf("Switch: [%ld] is invalid. Should be between 1 and 4.\n", sw); + return 1; + } + + // Make sure we've got a valid task. + char *task = argv[2]; + int taskOn = strcmp(task,"on"); + int taskOff = strcmp(task,"off"); + //printf("Raw task: [%s], taskOn: [%d], taskOff: [%d]\n", task, taskOn, taskOff); + if (taskOn == 0) { + printf("Turning the light on.\n"); + } else if (taskOff == 0) { + printf("Turning the light off.\n"); + } else { + printf("The task: [%s] is invalid. It must be 'on' or 'off'.\n", argv[2]); + printf("Usage: [%s ]. Switch is 1 ~ 4.\n", argv[0]); + return 1; + } + + // Set the pin to be an output + if (sw == 1) { + bcm2835_gpio_fsel(SW1, BCM2835_GPIO_FSEL_OUTP); + if (taskOn == 0) { + bcm2835_gpio_write(SW1, LOW); + } else { + bcm2835_gpio_write(SW1, HIGH); + } + } else if (sw == 2) { + bcm2835_gpio_fsel(SW2, BCM2835_GPIO_FSEL_OUTP); + if (taskOn == 0) { + bcm2835_gpio_write(SW2, LOW); + } else { + bcm2835_gpio_write(SW2, HIGH); + } + } else if (sw == 3) { + bcm2835_gpio_fsel(SW3, BCM2835_GPIO_FSEL_OUTP); + if (taskOn == 0) { + bcm2835_gpio_write(SW3, LOW); + } else { + bcm2835_gpio_write(SW3, HIGH); + } + } else if (sw == 4) { + bcm2835_gpio_fsel(SW4, BCM2835_GPIO_FSEL_OUTP); + if (taskOn == 0) { + bcm2835_gpio_write(SW4, LOW); + } else { + bcm2835_gpio_write(SW4, HIGH); + } + } + + return 0; +} + diff --git a/switch-control/arduino/switch-control.sketch b/switch-control/arduino/switch-control.sketch new file mode 100644 index 0000000..b949dff --- /dev/null +++ b/switch-control/arduino/switch-control.sketch @@ -0,0 +1,245 @@ +/* +Mermaid's Rest - Web-based digital switching +- Provide mechanical switch override to control lights via relays. When neither + the on or off switch is set for a given light, remote control is enabled and + the light/relay can be controlled from a web browser. + + - Digimer (Madison Kelly) - digital.mermaid@gmail.com + - https://www.youtube.com/@TheDigitalMermaid + +Version: 1.0.0 + - Release: Aug. 03, 2025 + +License: + - The GNU GPL v2.0 + */ + +#include +#include + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network: +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +IPAddress ip(10, 255, 6, 2); +IPAddress netmask(255, 255, 0, 0); +IPAddress dns(8, 8, 8, 8); +IPAddress gateway(10, 255, 255, 254); + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +EthernetServer server(80); + +#define tricolourOn A0 +#define tricolourOff A1 +#define tricolourOutput 2 +#define anchorOutput 3 +#define steamingOutput 4 +#define deckOutput 5 +#define lightOn LOW +#define lightOff HIGH + +// These will be set from the web client. +int tricolourWebValue = 0; +int anchorWebValue = 0; +int steamingWebValue = 0; +int deckWebValue = 0; + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + //Ethernet.init(10); // Most Arduino shields + //Ethernet.init(5); // MKR ETH shield + //Ethernet.init(0); // Teensy 2.0 + //Ethernet.init(20); // Teensy++ 2.0 + //Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + //Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + Serial.println("Mermaid's Rest - Digital Switch Controller"); + + // start the Ethernet connection and the server: + Ethernet.begin(mac, ip, dns, gateway, netmask); + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found."); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + // start the server + server.begin(); + Serial.print("server is at: ["); + Serial.print(Ethernet.localIP()); + Serial.print("/"); + Serial.print(Ethernet.subnetMask()); + Serial.print("], Gateway: ["); + Serial.print(Ethernet.gatewayIP()); + Serial.print("], using DNS: ["); + Serial.print(Ethernet.dnsServerIP()); + Serial.println("]"); + + // Set analog pins to digital mode using the internal pull-up resistors + pinMode(tricolourOn, INPUT); + pinMode(tricolourOn, INPUT_PULLUP); + pinMode(tricolourOff, INPUT); + pinMode(tricolourOff, INPUT_PULLUP); + + // Turn off the digital output pin + pinMode(tricolourOutput, OUTPUT); + pinMode(anchorOutput, OUTPUT); + pinMode(steamingOutput, OUTPUT); + pinMode(deckOutput, OUTPUT); + digitalWrite(tricolourOutput, lightOff); + digitalWrite(anchorOutput, lightOff); + digitalWrite(steamingOutput, lightOff); + digitalWrite(deckOutput, lightOff); +} + +void loop() { + // Handle switches + int tricolourOnValue = digitalRead(tricolourOn) ? 0 : 1; + int tricolourOffValue = digitalRead(tricolourOff) ? 0 : 1; + int tricolourRemoteValue = (!tricolourOnValue && !tricolourOffValue) ? 1 : 0; + int tricolourOutputValue = digitalRead(tricolourOutput) ? 0 : 1; + int anchorOutputValue = digitalRead(anchorOutput) ? 0 : 1; + int steamingOutputValue = digitalRead(steamingOutput) ? 0 : 1; + int deckOutputValue = digitalRead(deckOutput) ? 0 : 1; + Serial.print("Switches; Tricolour Light: ["); + Serial.print(tricolourOutputValue); + Serial.print("], Anchor Light: ["); + Serial.print(anchorOutputValue); + Serial.print("], Steaming Light: ["); + Serial.print(steamingOutputValue); + Serial.print("], Deck Light: ["); + Serial.print(deckOutputValue); + Serial.println("]"); + if (tricolourOnValue) + { + // Is the switch on? If not, turn it on. + if (!tricolourOutputValue) + { + // Turn on the relay + Serial.print("Manual control; Turning on tricolour switch: ["); + Serial.print(tricolourOutput); + Serial.println("]"); + digitalWrite(tricolourOutput, lightOn); + } + } + else if (tricolourOffValue) + { + // Is the switch off? If not, turn it off. + if (tricolourOutputValue) + { + // Turn on the relay + Serial.print("Manual control; Turning off tricolour switch: ["); + Serial.print(tricolourOutput); + Serial.println("]"); + digitalWrite(tricolourOutput, lightOff); + } + } + else + { + // Read from the web UI + if ((tricolourWebValue) && (!tricolourOutputValue)) + { + // Turn on the relay + Serial.print("Remote control; Turning on tricolour switch: ["); + Serial.print(tricolourOutput); + Serial.println("]"); + digitalWrite(tricolourOutput, lightOn); + } + else if ((!tricolourWebValue) && (tricolourOutputValue)) + { + // Turn off the relay + Serial.print("Remote control; Turning off tricolour switch: ["); + Serial.print(tricolourOutput); + Serial.println("]"); + digitalWrite(tricolourOutput, lightOff); + } + } + // listen for incoming clients + EthernetClient client = server.available(); + if (client) { + Serial.println("new client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + Serial.write(c); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); // the connection will be closed after completion of the response + client.println("Refresh: 5"); // refresh the page automatically every 5 sec + client.println(); + client.println(""); + client.println(""); + client.println(""); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println(" "); + client.println("
Mermaid's Rest - Switch Controller
Tricolour On:"); + client.print(tricolourOnValue); + client.println(" Off:"); + client.print(tricolourOffValue); + client.println(" Remote:"); + client.print(tricolourRemoteValue); + client.println(" Output:"); + client.print(tricolourOutputValue); + client.println("
"); + + /* + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + int sensorReading = analogRead(analogChannel); + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(sensorReading); + client.println("
"); + } + */ + client.println(""); + break; + } + if (c == '\n') { + // you're starting a new line + currentLineIsBlank = true; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + Serial.println("client disconnected"); + } + delay(1000); +}