Add C++ Gpio driver
This commit is contained in:
		
							
								
								
									
										101
									
								
								platform/stm32g0xx/Gpio.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								platform/stm32g0xx/Gpio.cc
									
									
									
									
									
										Normal file
									
								
							@@ -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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								platform/stm32g0xx/Gpio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								platform/stm32g0xx/Gpio.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
#ifndef __PLATFORM_STM32G0XX_GPIO_H__
 | 
			
		||||
#define __PLATFORM_STM32G0XX_GPIO_H__
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
		Reference in New Issue
	
	Block a user