#ifndef __STM_PIN_HPP__ #define __STM_PIN_HPP__ //#include "../../interfaces/pin.hpp" //#include "../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f042x6.h" #include #include #define MODER_IN 0x0UL #define MODER_OUT 0x1UL #define MODER_ALTERNATE 0x2UL #define MODER_ANALOG 0x3UL #define OSPEEDR_LOW 0x0UL #define OSPEEDR_MEDIUM 0x1UL #define OSPEEDR_HIGH 0x3UL #define PUPDR_NO_PULL 0x0UL #define PUPDR_PULL_UP 0x1UL #define PUPDR_PULL_DOWN 0x2UL // https://accu.org/journals/overload/13/68/goodliffe_281/ #define LQFP32 // TODO : If that makes sens it will be implmendet on the Cmake. // How can we check the assert for each port ? #ifdef LQFP32 #define PORT_A_PIN_COUNT 15 #define PORT_B_PIN_COUNT 8 #define PORT_C_PIN_COUNT 0 #define PORT_F_PIN_COUNT 2 // 0b1111 1111 Means all the piuns are present it's to de bale to make an & comprison #define PORT_A_PIN_MISSING_MSK 0xFF #define PORT_B_PIN_MISSING_MSK 0xFB #define PORT_C_PIN_MISSING_MSK 0x00 #define PORT_F_PIN_MISSING_MSK 0xFC #endif enum GPIO_Port { Port_A_base_address = GPIOA_BASE, // 0x4800'0000 Port_B_base_address = GPIOB_BASE, // 0x4800'0400 Port_C_base_address = GPIOC_BASE, // 0x4800'0800 Port_F_base_address = GPIOF_BASE // 0x4800'1400 }; enum Pin_no{ pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_8, pin_9, pin_10, pin_11, pin_12, pin_13, pin_14, pin_15 }; template class STM_Pin : Pin { public: STM_Pin() { static_assert(pin_no < PORT_A_PIN_COUNT, "GPIO has only 14 ports!"); } void setMode(mode mode) override { switch (mode) { case undefined: return; // TODO : Implement some sort of error break; case input: reinterpret_cast(port_base_address)->MODER &= ~(MODER_IN << (pin_no * 2)); return; case output: reinterpret_cast(port_base_address)->MODER |= (MODER_OUT << (pin_no * 2)); return; case analog: reinterpret_cast(port_base_address)->MODER |= (MODER_ANALOG << (pin_no * 2)); return; case alternate: reinterpret_cast(port_base_address)->MODER |= (MODER_ALTERNATE << (pin_no * 2)); return; default: reinterpret_cast(port_base_address)->MODER |= (MODER_ANALOG << (pin_no * 2)); break; }; } void setOutputState(state state) override { // TODO: test it! switch (state) { case openDrain: reinterpret_cast(port_base_address)->OTYPER |= (1UL << pin_no); return; break; case pushPull: reinterpret_cast(port_base_address)->OTYPER &= ~(1UL << pin_no); return; break; case floating: break; default: break; }; } void setPullUpDonw(pullUpDown resistance) override { switch(resistance) { case none: reinterpret_cast(port_base_address)->PUPDR &= ~(PUPDR_NO_PULL << (2 * pin_no)); return; case pullUp: reinterpret_cast(port_base_address)->PUPDR |= (PUPDR_PULL_UP << (2 * pin_no)); return; case pullDown: reinterpret_cast(port_base_address)->PUPDR |= (PUPDR_PULL_DOWN << (2 * pin_no)); return; default: break; }; } void setSpeed(speed speed) override { //reinterpret_cast(port_base_address)->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0_Msk << (2 * pin_no)); switch(speed) { case slow: reinterpret_cast(port_base_address)->OSPEEDR &= ~(OSPEEDR_LOW << (2 * pin_no)); return; case normal: reinterpret_cast(port_base_address)->OSPEEDR |= (OSPEEDR_MEDIUM << (2 * pin_no)); return; case fast: reinterpret_cast(port_base_address)->OSPEEDR |= (OSPEEDR_HIGH << (2 * pin_no)); return; case veryFast: return; default: break; }; } void config(mode mode, state state, pullUpDown resistance, speed speed) override { } bool read() override { return (reinterpret_cast(port_base_address)->IDR & (1<> pin_no; } void toggle() override { } void write(bool state) override { if(state) { reinterpret_cast(port_base_address)->BSRR |= (GPIO_BSRR_BS_0 << pin_no); return; } reinterpret_cast(port_base_address)->BSRR |= (GPIO_BSRR_BR_0<< pin_no); } void init() override { // TODO: find better way switch (port_base_address) { case GPIOA_BASE: RCC->AHBENR |= RCC_AHBENR_GPIOAEN; return; break; case GPIOB_BASE: RCC->AHBENR |= RCC_AHBENR_GPIOBEN; return; break; case GPIOC_BASE: RCC->AHBENR |= RCC_AHBENR_GPIOCEN; return; break; case GPIOF_BASE: RCC->AHBENR |= RCC_AHBENR_GPIOFEN; return; break; default: break; }; } void deInit() override { } void hardwareInfo() override { } private: void throwError(uint16_t line, errors errNo) override { } }; #endif //__STM_PIN_HPP__