You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
6.3 KiB
232 lines
6.3 KiB
#ifndef __STM_PIN_HPP__
|
|
#define __STM_PIN_HPP__
|
|
|
|
//#include "../../interfaces/pin.hpp"
|
|
//#include "../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f042x6.h"
|
|
#include <array>
|
|
#include <stdint.h>
|
|
|
|
#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 <Pin_no pin_no, GPIO_Port port_base_address>
|
|
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<GPIO_TypeDef*>(port_base_address)->MODER &= ~(MODER_IN << (pin_no * 2));
|
|
return;
|
|
case output:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->MODER |= (MODER_OUT << (pin_no * 2));
|
|
return;
|
|
case analog:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->MODER |= (MODER_ANALOG << (pin_no * 2));
|
|
return;
|
|
case alternate:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->MODER |= (MODER_ALTERNATE << (pin_no * 2));
|
|
return;
|
|
default:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->MODER |= (MODER_ANALOG << (pin_no * 2));
|
|
break;
|
|
};
|
|
}
|
|
|
|
void setOutputState(state state) override
|
|
{
|
|
// TODO: test it!
|
|
switch (state)
|
|
{
|
|
case openDrain:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->OTYPER |= (1UL << pin_no);
|
|
return;
|
|
break;
|
|
case pushPull:
|
|
reinterpret_cast<GPIO_TypeDef*>(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<GPIO_TypeDef*>(port_base_address)->PUPDR &= ~(PUPDR_NO_PULL << (2 * pin_no));
|
|
return;
|
|
case pullUp:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->PUPDR |= (PUPDR_PULL_UP << (2 * pin_no));
|
|
return;
|
|
case pullDown:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->PUPDR |= (PUPDR_PULL_DOWN << (2 * pin_no));
|
|
return;
|
|
default:
|
|
break;
|
|
};
|
|
|
|
}
|
|
|
|
void setSpeed(speed speed) override
|
|
{
|
|
//reinterpret_cast<GPIO_TypeDef*>(port_base_address)->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0_Msk << (2 * pin_no));
|
|
switch(speed) {
|
|
case slow:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->OSPEEDR &= ~(OSPEEDR_LOW << (2 * pin_no));
|
|
return;
|
|
case normal:
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->OSPEEDR |= (OSPEEDR_MEDIUM << (2 * pin_no));
|
|
return;
|
|
case fast:
|
|
reinterpret_cast<GPIO_TypeDef*>(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<GPIO_TypeDef*>(port_base_address)->IDR & (1<<pin_no)) >> pin_no;
|
|
}
|
|
|
|
void toggle() override
|
|
{
|
|
|
|
}
|
|
|
|
void write(bool state) override
|
|
{
|
|
|
|
if(state) {
|
|
reinterpret_cast<GPIO_TypeDef*>(port_base_address)->BSRR |= (GPIO_BSRR_BS_0 << pin_no);
|
|
return;
|
|
}
|
|
reinterpret_cast<GPIO_TypeDef*>(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__
|