diff --git a/Core/main.cc b/Core/main.cc index b67de4c..6a0e9af 100644 --- a/Core/main.cc +++ b/Core/main.cc @@ -11,7 +11,6 @@ IWDG_HandleTypeDef hiwdg; UART_HandleTypeDef huart2; static void SystemClock_Config(void); -static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); // static void MX_IWDG_Init(void); @@ -24,6 +23,8 @@ class My ~My() {printf("Destructor\r\n");}; }; +using namespace perinet::platform::stm32g0xx; + int main(void) { unsigned int i = 1, j = 40; @@ -44,13 +45,14 @@ int main(void) MODIFY_REG(SYSCFG->CFGR1, (SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE), SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE); SystemClock_Config(); - MX_GPIO_Init(); MX_USART2_UART_Init(); My* my = new My(); delete(my); + Gpio green_led(Gpio::Port::PORT_A, 5, Gpio::Mode::MODE_OUTPUT_PP); + // MX_IWDG_Init(); while (1) { if (j < 100) { @@ -66,11 +68,7 @@ int main(void) j = 800; } printf("%u: Hello World\r\n", i++); -<<<<<<< HEAD - HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); -======= green_led.toggle(); ->>>>>>> 133286e (fix: format) HAL_Delay(j); // HAL_IWDG_Refresh(&hiwdg); } @@ -172,49 +170,6 @@ static void MX_USART2_UART_Init(void) } } -static void MX_GPIO_Init(void) -{ - /* Enable PORT C clock*/ - SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); - /* Delay after an RCC peripheral clock enabling */ - READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); - - /* Enable PORT F clock*/ - SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); - /* Delay after an RCC peripheral clock enabling */ - READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); - - /* Enable PORT A clock*/ - SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); - /* Delay after an RCC peripheral clock enabling */ - READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); - - GPIOA->BSRR = 1 << 5; // PORTA PIN5 (green LED) - - /* Configure the IO Speed */ - uint32_t temp = GPIOA->OSPEEDR; - temp &= ~(GPIO_OSPEEDR_OSPEED0 << (5 * 2u)); - temp |= (GPIO_SPEED_FREQ_HIGH << (5 * 2u)); - GPIOA->OSPEEDR = temp; - - /* Configure the IO Output Type */ - temp = GPIOA->OTYPER; - temp &= ~(GPIO_OTYPER_OT0 << 5); - temp |= (((GPIO_MODE_OUTPUT_PP & 0x00000010u) >> 4u) << 5); - GPIOA->OTYPER = temp; - - /* Activate the Pull-up or Pull down resistor for the current IO */ - temp = GPIOA->PUPDR; - temp &= ~(GPIO_PUPDR_PUPD0 << (5 * 2u)); - temp |= ((GPIO_NOPULL) << (5 * 2u)); - GPIOA->PUPDR = temp; - - /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ - temp = GPIOA->MODER; - temp &= ~(GPIO_MODER_MODE0 << (5 * 2u)); - temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003u) << (5 * 2u)); - GPIOA->MODER = temp; -} void Error_Handler(void) { diff --git a/platform/stm32g0xx/Gpio.cc b/platform/stm32g0xx/Gpio.cc new file mode 100644 index 0000000..994dd1e --- /dev/null +++ b/platform/stm32g0xx/Gpio.cc @@ -0,0 +1,101 @@ +#include "stm32g0xx.h" + +#include "platform/stm32g0xx/Gpio.h" + +using namespace perinet::platform::stm32g0xx; + +Gpio::Gpio(Port port, uint32_t pin, Mode mode, Pullup pullup, AlternateFunction alternate_function) +{ + switch(port) { + case Port::PORT_A: + this->port = GPIOA; + /* Enable PORT A clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); + break; + case Port::PORT_B: + this->port = GPIOB; + /* Enable PORT B clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); + break; + case Port::PORT_C: + this->port = GPIOC; + /* Enable PORT C clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); + break; + case Port::PORT_D: + this->port = GPIOD; + /* Enable PORT D clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN); + break; + case Port::PORT_F: + this->port = GPIOF; + /* Enable PORT F clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); + break; + } + this->pin = pin; + + /* Configure the IO Speed */ + volatile uint32_t temp = this->port->OSPEEDR; + temp &= ~(GPIO_OSPEEDR_OSPEED0 << (this->pin * 2u)); + temp |= (static_cast(Speed::FREQ_HIGH) << (this->pin * 2u)); + this->port->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = this->port->OTYPER; + temp &= ~(GPIO_OTYPER_OT0 << this->pin); + temp |= (((static_cast(mode) & 0x00000010u) >> 4u) << this->pin); + this->port->OTYPER = temp; + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = this->port->PUPDR; + temp &= ~(GPIO_PUPDR_PUPD0 << (this->pin * 2u)); + temp |= ((static_cast(pullup)) << (this->pin * 2u)); + this->port->PUPDR = temp; + + /* Configure Alternate function mapped with the current IO */ + temp = this->port->AFR[this->pin >> 3u]; + temp &= ~(0xFu << ((this->pin & 0x07u) * 4u)); + temp |= ((static_cast(alternate_function)) << ((this->pin & 0x07u) * 4u)); + this->port->AFR[this->pin >> 3u] = temp; + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = this->port->MODER; + temp &= ~(GPIO_MODER_MODE0 << (this->pin * 2u)); + temp |= ((static_cast(mode) & 0x00000003u) << (this->pin * 2u)); + this->port->MODER = temp; +} + +void Gpio::set() +{ + this->port->BSRR = 1 << this->pin; +} + +void Gpio::clear() +{ + this->port->BRR = 1 << this->pin; +} + +void Gpio::toggle() +{ + // get current Output Data Register value + volatile uint32_t odr = this->port->ODR; + + // Set selected pins that were at low level, and reset ones that were high + this->port->BSRR = ((odr & (1 << this->pin)) << 16) | (~odr & (1 << this->pin)); +} + +uint32_t Gpio::get() +{ + return (this->port->IDR & (1 << this->pin)) >> this->pin; +} \ No newline at end of file diff --git a/platform/stm32g0xx/Gpio.h b/platform/stm32g0xx/Gpio.h new file mode 100644 index 0000000..2c2a6c7 --- /dev/null +++ b/platform/stm32g0xx/Gpio.h @@ -0,0 +1,76 @@ +#ifndef __PLATFORM_STM32G0XX_GPIO_H__ +#define __PLATFORM_STM32G0XX_GPIO_H__ + +#include + +#include "stm32g071xx.h" + +namespace perinet::platform::stm32g0xx { + +class Gpio +{ +public: + enum class Port + { + PORT_A, + PORT_B, + PORT_C, + PORT_D, + PORT_F + }; + + enum class Speed + { + FREQ_LOW = 0, // Low speed + FREQ_MEDIUM, // Medium speed + FREQ_HIGH, // High speed + FREQ_VERY_HIGH // Very high speed + }; + + enum class Mode + { + MODE_INPUT = 0x00, // Input Floating Mode + MODE_OUTPUT_PP = 0x01, // Output Push Pull Mode + MODE_AF_PP = 0x02, // Alternate Function Push Pull Mode + MODE_ANALOG = 0x03, // Analog Mode + MODE_OUTPUT_OD = 0x11, // Output Open Drain Mode + MODE_AF_OD = 0x12, // Alternate Function Open Drain Mode + }; + + enum class Pullup + { + NOPULL = 0, // No Pull-up or Pull-down activation + PULLUP, // Pull-up activation + PULLDOWN // Pull-down activation + }; + + enum class AlternateFunction + { + ALTERNATE_FUNCTION_0 = 0, + ALTERNATE_FUNCTION_1, + ALTERNATE_FUNCTION_2, + ALTERNATE_FUNCTION_3, + ALTERNATE_FUNCTION_4, + ALTERNATE_FUNCTION_5, + ALTERNATE_FUNCTION_6, + ALTERNATE_FUNCTION_7, + ALTERNATE_FUNCTION_8, + ALTERNATE_FUNCTION_9, + ALTERNATE_FUNCTION_10, + }; + + Gpio(Port, uint32_t, Mode=Mode::MODE_INPUT, Pullup=Pullup::NOPULL, AlternateFunction=AlternateFunction::ALTERNATE_FUNCTION_0); + + uint32_t get(); + void set(); + void clear(); + void toggle(); + +private: + GPIO_TypeDef *port; + uint32_t pin; +}; + +} + +#endif