CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
platform-gpio.hh
1#pragma once
2#include <cdefs.h>
3#include <stdint.h>
4
5/**
6 * The Arty A7 configuration has two LEDs (LD5 and LD6), four buttons, and four
7 * switches, exposed over GPIO.
8 *
9 * This provides a simple driver for them.
10 */
11struct GPIO
12{
13 /**
14 * Input register. This is unused for the LEDs.
15 */
16 uint32_t read;
17 /**
18 * The output register. This is a bitmap of GPIO lines to set.
19 */
20 uint32_t write;
21 /**
22 * Write enable. This sets the pins that should be controlled by `write`.
23 */
24 uint32_t writeEnable;
25
26 /**
27 * The index of the first GPIO pin connected to a LED.
28 */
29 static constexpr uint32_t FirstLED = 14;
30 /**
31 * The index of the last GPIO pin connected to a LED.
32 */
33 static constexpr uint32_t LastLED = 15;
34 /**
35 * The number of GPIO pins used for LEDs.
36 */
37 static constexpr uint32_t LEDCount = LastLED - FirstLED + 1;
38
39 /**
40 * Helper that defines a set of bits in a GPIO input word used for a
41 * specific purpose.
42 */
43 struct InputBits
44 {
45 /**
46 * The number of bits.
47 */
48 const uint32_t Count;
49
50 /**
51 * The offset of the lowest bit in the GPIO input word.
52 */
53 const uint32_t Shift;
54
55 /**
56 * The mask used to extract the bits.
57 */
58 [[nodiscard]] constexpr uint32_t mask() const
59 {
60 return (1 << Count) - 1;
61 }
62
63 /**
64 * Extract the bits for this range.
65 */
66 [[nodiscard]] __always_inline uint32_t extract(uint32_t value) const
67 {
68 return (value >> Shift) & mask();
69 }
70 };
71
72 /**
73 * The buttons zero to three are in the low four bits.
74 */
75 static constexpr InputBits Buttons = {4, 4};
76
77 /**
78 * Switches zero to three are in the next four bits.
79 */
80 static constexpr InputBits Switches = {4, 0};
81
82 /**
83 * Helper to read all of the bits defined by an `InputBits` instance.
84 */
85 template<InputBits Bits>
86 __always_inline uint32_t bits() volatile
87 {
88 return Bits.extract(read);
89 }
90
91 /**
92 * Helper to read a single bit defined by an `InputBits` instance.
93 */
94 template<InputBits Bits>
95 __always_inline uint32_t bit(uint32_t index) volatile
96 {
97 return (Bits.extract(read) >> index) & 1;
98 }
99
100 /**
101 * Read the value of all of the buttons.
102 */
103 uint32_t buttons() volatile
104 {
105 return bits<Buttons>();
106 }
107
108 /**
109 * Read the value of all of the switches.
110 */
111 uint32_t switches() volatile
112 {
113 return bits<Switches>();
114 }
115
116 /**
117 * Read the value of one of the buttons, indicated by index.
118 */
119 uint32_t button(uint32_t index) volatile
120 {
121 return bit<Buttons>(index);
122 }
123
124 /**
125 * Read the value of one of the switches, indicated by index.
126 *
127 * This should be called `switch`, but that's a keyword in C/C++.
128 */
129 uint32_t switch_value(uint32_t index) volatile
130 {
131 return bit<Switches>(index);
132 }
133
134 /**
135 * Helper that maps from an LED index to a bit to set / clear to control
136 * that LED. Returns 0 for out-of-bounds LED values and so can be safely
137 * masked.
138 */
139 constexpr static uint32_t led_bit(uint32_t index)
140 {
141 if (index >= LEDCount)
142 {
143 return 0;
144 }
145 return 1 << (index + FirstLED);
146 }
147
148 /**
149 * Enable all of the LED GPIO pins.
150 *
151 * This must be called before `led_on` or `led_off`.
152 */
153 void enable_all() volatile
154 {
155 uint32_t bitmap = 0;
156 for (uint32_t i = 0; i < LEDCount; i++)
157 {
158 bitmap |= led_bit(i);
159 }
160 writeEnable = bitmap;
161 }
162
163 /**
164 * Turn on the LED specified by `index`.
165 */
166 void led_on(uint32_t index) volatile
167 {
168 write = write | led_bit(index);
169 }
170
171 /**
172 * Turn off the LED specified by `index`.
173 */
174 void led_off(uint32_t index) volatile
175 {
176 write = write & ~led_bit(index);
177 }
178};
Helper that defines a set of bits in a GPIO input word used for a specific purpose.
uint32_t extract(uint32_t value) const
Extract the bits for this range.
constexpr uint32_t mask() const
The mask used to extract the bits.
const uint32_t Count
The number of bits.
const uint32_t Shift
The offset of the lowest bit in the GPIO input word.
The Arty A7 configuration has two LEDs (LD5 and LD6), four buttons, and four switches,...
static constexpr InputBits Buttons
The buttons zero to three are in the low four bits.
uint32_t bit(uint32_t index) volatile
Helper to read a single bit defined by an InputBits instance.
void led_on(uint32_t index) volatile
Turn on the LED specified by index.
void enable_all() volatile
Enable all of the LED GPIO pins.
uint32_t button(uint32_t index) volatile
Read the value of one of the buttons, indicated by index.
static constexpr uint32_t LastLED
The index of the last GPIO pin connected to a LED.
static constexpr uint32_t LEDCount
The number of GPIO pins used for LEDs.
static constexpr uint32_t led_bit(uint32_t index)
Helper that maps from an LED index to a bit to set / clear to control that LED.
uint32_t switches() volatile
Read the value of all of the switches.
uint32_t writeEnable
Write enable.
static constexpr uint32_t FirstLED
The index of the first GPIO pin connected to a LED.
uint32_t read
Input register.
uint32_t bits() volatile
Helper to read all of the bits defined by an InputBits instance.
uint32_t switch_value(uint32_t index) volatile
Read the value of one of the switches, indicated by index.
static constexpr InputBits Switches
Switches zero to three are in the next four bits.
uint32_t buttons() volatile
Read the value of all of the buttons.
void led_off(uint32_t index) volatile
Turn off the LED specified by index.
uint32_t write
The output register.