Blame view

build3/ion/src/device/regs/gpio.h 2.83 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  #ifndef REGS_GPIO_H
  #define REGS_GPIO_H
  
  #include "register.h"
  
  class GPIO {
  public:
    class MODER : public Register32 {
    public:
      enum class Mode {
        Input = 0,
        Output = 1,
        AlternateFunction = 2,
        Analog = 3
      };
      Mode getMode(int index) { return (Mode)getBitRange(2*index+1, 2*index); }
      void setMode(int index, Mode mode) volatile { setBitRange(2*index+1, 2*index, (uint32_t)mode); }
    };
  
    class OTYPER : Register32 {
    public:
      enum class Type {
        PushPull = 0,
        OpenDrain = 1
      };
      Type getType(int index) { return (Type)getBitRange(index, index); }
      void setType(int index, Type type) volatile { setBitRange(index, index, (uint32_t)type); }
    };
  
    class PUPDR : public Register32 {
    public:
      enum class Pull {
        None = 0,
        Up = 1,
        Down = 2,
        Reserved = 3
      };
      Pull getPull(int index) { return (Pull)getBitRange(2*index+1, 2*index); }
      void setPull(int index, Pull pull) volatile { setBitRange(2*index+1, 2*index, (uint32_t)pull); }
    };
  
    class IDR : public Register32 {
    public:
      bool get(int index) volatile { return (bool)getBitRange(index, index); }
    };
  
    class ODR : public Register32 {
    public:
      bool get(int index) volatile { return (bool)getBitRange(index, index); }
      void set(int index, bool state) volatile { setBitRange(index, index, state); }
    };
  
    class AFR : Register64 {
      /* The AFR register doesn't exist per-se in the documentation. It is the
       * consolidation of AFRL and AFRH which are two 32 bits registers. */
    public:
      enum class AlternateFunction {
        AF0 = 0,   AF1 = 1,   AF2 = 2,   AF3 = 3,
        AF4 = 4,   AF5 = 5,   AF6 = 6,   AF7 = 7,
        AF8 = 8,   AF9 = 9,   AF10 = 10, AF11 = 11,
        AF12 = 12, AF13 = 13, AF14 = 14, AF15 = 15
      };
      AlternateFunction getAlternateFunction(int index) {
        return (AlternateFunction)getBitRange(4*index+3, 4*index);
      }
      void setAlternateFunction(int index, AlternateFunction af) volatile {
        setBitRange(4*index+3, 4*index, (uint64_t)af);
      }
    };
  
    constexpr GPIO(int i) : m_index(i) {}
    constexpr operator int() const { return m_index; }
    REGS_REGISTER_AT(MODER, 0x00);
    REGS_REGISTER_AT(OTYPER, 0x04);
    REGS_REGISTER_AT(PUPDR, 0x0C);
    REGS_REGISTER_AT(IDR, 0x10);
    REGS_REGISTER_AT(ODR, 0x14);
    REGS_REGISTER_AT(AFR, 0x20);
  private:
    constexpr uint32_t Base() const {
      return 0x40020000 + 0x400*m_index;
    };
    int m_index;
  };
  
  constexpr GPIO GPIOA(0);
  constexpr GPIO GPIOB(1);
  constexpr GPIO GPIOC(2);
  constexpr GPIO GPIOD(3);
  constexpr GPIO GPIOE(4);
  constexpr GPIO GPIOF(5);
  constexpr GPIO GPIOG(6);
  constexpr GPIO GPIOH(7);
  
  class GPIOPin {
  public:
    constexpr GPIOPin(GPIO group, uint8_t pin) : m_data(((group&0xF) << 4) | (pin&0xF)) {}
    GPIO group() const { return GPIO(m_data>>4); }
    uint8_t pin() const { return m_data & 0xF; }
  private:
    uint8_t m_data;
  };
  
  #endif