Skip to content

Commit 8a5c4ad

Browse files
twasilczyksalkinium
authored andcommitted
Implement GPIO support for SAMV
1 parent a5a776c commit 8a5c4ad

File tree

4 files changed

+50
-68
lines changed

4 files changed

+50
-68
lines changed

src/modm/platform/gpio/sam/config.hpp.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ struct Peripherals::{{ name }}::{{ signal }}<{{ index }}> {};
7575

7676
enum class PortName
7777
{
78-
A,
79-
B,
78+
%% for port in ports
79+
{{ port }},
80+
%% endfor
8081
};
8182

8283
template<class _>

src/modm/platform/gpio/sam/enable.cpp.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void
1616
modm_gpio_enable(void)
1717
{
1818

19-
%% if target["family"] in ["g"]
19+
%% if target["family"] in ["g", "v"]
2020

2121
PMC->PMC_PCER0 =
2222
%% for port in options["enable_ports"]

src/modm/platform/gpio/sam/module.lb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def validate(env):
5858
driver = device.get_driver("gpio")
5959

6060
def build(env):
61-
bprops = env.substitutions
6261
device = env[":target"]
6362
driver = device.get_driver("gpio")
6463

src/modm/platform/gpio/sam/pin.hpp.in

Lines changed: 46 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct OneOfSignals
8989
static constexpr bool value = ((std::is_same_v<typename Signal::signal, Signals>) | ...);
9090
};
9191

92-
%% if target["family"] in ["g"]
92+
%% if target["family"] in ["g", "v"]
9393

9494
template<class... PinConfigs>
9595
struct PinMuxMixin
@@ -105,15 +105,13 @@ struct PinMuxMixin<PinConfig, PinConfigs...>
105105
{
106106
uint8_t bit0 = cfg & 1;
107107
uint8_t bit1 = (cfg & 2) >> 1;
108-
if constexpr (PinConfig::port == PortName::A)
108+
%% for port in ports
109+
if constexpr (PinConfig::port == PortName::{{ port }})
109110
{
110-
PIOA->PIO_ABCDSR[0] = (PIOA->PIO_ABCDSR[0] & ~(1<<PinConfig::pin)) | (bit0 << PinConfig::pin);
111-
PIOA->PIO_ABCDSR[1] = (PIOA->PIO_ABCDSR[1] & ~(1<<PinConfig::pin)) | (bit1 << PinConfig::pin);
112-
} else if constexpr (PinConfig::port == PortName::B)
113-
{
114-
PIOB->PIO_ABCDSR[0] = (PIOB->PIO_ABCDSR[0] & ~(1<<PinConfig::pin)) | (bit0 << PinConfig::pin);
115-
PIOB->PIO_ABCDSR[1] = (PIOB->PIO_ABCDSR[1] & ~(1<<PinConfig::pin)) | (bit1 << PinConfig::pin);
111+
PIO{{ port }}->PIO_ABCDSR[0] = (PIO{{ port }}->PIO_ABCDSR[0] & ~(1<<PinConfig::pin)) | (bit0 << PinConfig::pin);
112+
PIO{{ port }}->PIO_ABCDSR[1] = (PIO{{ port }}->PIO_ABCDSR[1] & ~(1<<PinConfig::pin)) | (bit1 << PinConfig::pin);
116113
}
114+
%% endfor
117115
PinMuxMixin<PinConfigs...>::set(cfg);
118116
}
119117
};
@@ -134,36 +132,33 @@ protected:
134132
inline static constexpr volatile uint32_t*
135133
getPortReg(size_t offset)
136134
{
137-
if constexpr (port == PortName::A) {
138-
return (uint32_t*)((uint8_t*)PIOA + offset);
139-
}
140-
if constexpr (port == PortName::B) {
141-
return (uint32_t*)((uint8_t*)PIOB + offset);
135+
%% for port in ports
136+
if constexpr (port == PortName::{{ port }}) {
137+
return (uint32_t*)((uint8_t*)PIO{{ port }} + offset);
142138
}
139+
%% endfor
143140
}
144141

145142
inline static constexpr void
146143
setPortReg(size_t offset)
147144
{
148-
if constexpr (mask(PortName::A) != 0) { *getPortReg<PortName::A>(offset) = mask(PortName::A); }
149-
if constexpr (mask(PortName::B) != 0) { *getPortReg<PortName::B>(offset) = mask(PortName::B); }
145+
%% for port in ports
146+
if constexpr (mask(PortName::{{ port }}) != 0) { *getPortReg<PortName::{{ port }}>(offset) = mask(PortName::{{ port }}); }
147+
%% endfor
150148
}
151149

152150
template<PortName port>
153151
inline static constexpr uint32_t
154152
readPortReg(size_t offset)
155153
{
156-
if constexpr (port == PortName::A)
154+
%% for port in ports
155+
if constexpr (port == PortName::{{ port }})
157156
{
158-
static_assert(mask(PortName::A) != 0,
159-
"Trying to read port which is not in the GpioSet!");
160-
return *getPortReg<PortName::A>(offset) & mask(PortName::A);
161-
} else if constexpr (port == PortName::B)
162-
{
163-
static_assert(mask(PortName::B) != 0,
164-
"Trying to read port which is not in the GpioSet!");
165-
return *getPortReg<PortName::B>(offset) & mask(PortName::B);
157+
static_assert(mask(PortName::{{ port }}) != 0,
158+
"Trying to read port which is not in the GpioSet!");
159+
return *getPortReg<PortName::{{ port }}>(offset) & mask(PortName::{{ port }});
166160
}
161+
%% endfor
167162
}
168163

169164
public:
@@ -236,18 +231,14 @@ public:
236231
static void
237232
toggle()
238233
{
239-
if constexpr (mask(PortName::A) != 0) {
240-
volatile uint32_t *reg = getPortReg<PortName::A>(PIO_ODSR_OFFSET);
234+
%% for port in ports
235+
if constexpr (mask(PortName::{{ port }}) != 0) {
236+
volatile uint32_t *reg = getPortReg<PortName::{{ port }}>(PIO_ODSR_OFFSET);
241237
uint32_t tmp = *reg;
242-
tmp ^= mask(PortName::A);
243-
*reg = tmp;
244-
}
245-
if constexpr (mask(PortName::B) != 0) {
246-
volatile uint32_t *reg = getPortReg<PortName::B>(PIO_ODSR_OFFSET);
247-
uint32_t tmp = *reg;
248-
tmp ^= mask(PortName::B);
238+
tmp ^= mask(PortName::{{ port }});
249239
*reg = tmp;
250240
}
241+
%% endfor
251242
}
252243

253244
static void
@@ -271,13 +262,10 @@ struct PinCfgMixin<PinConfig, PinConfigs...>
271262
inline static void
272263
set(uint8_t cfg)
273264
{
274-
if constexpr (PinConfig::port == PortName::A)
275-
{
276-
PORT->Group[0].PINCFG[PinConfig::pin].reg = cfg;
277-
} else if constexpr (PinConfig::port == PortName::B)
278-
{
279-
PORT->Group[1].PINCFG[PinConfig::pin].reg = cfg;
280-
}
265+
%% for port in ports
266+
if constexpr (PinConfig::port == PortName::{{ port }})
267+
PORT->Group[{{loop.index0}}].PINCFG[PinConfig::pin].reg = cfg;
268+
%% endfor
281269
PinCfgMixin<PinConfigs...>::set(cfg);
282270
}
283271
};
@@ -298,36 +286,31 @@ protected:
298286
inline static constexpr volatile uint32_t*
299287
getPortReg(size_t offset)
300288
{
301-
if constexpr (port == PortName::A) {
302-
return (uint32_t*)(&PORT->Group[0]) + offset / sizeof(uint32_t);
303-
}
304-
if constexpr (port == PortName::B) {
305-
return (uint32_t*)(&PORT->Group[1]) + offset / sizeof(uint32_t);
306-
}
289+
%% for port in ports
290+
if constexpr (port == PortName::{{port}})
291+
return (uint32_t*)(&PORT->Group[{{loop.index0}}]) + offset / sizeof(uint32_t);
292+
%% endfor
307293
}
308294

309295
inline static constexpr void
310296
setPortReg(size_t offset)
311297
{
312-
if constexpr (mask(PortName::A) != 0) { *getPortReg<PortName::A>(offset) = mask(PortName::A); }
313-
if constexpr (mask(PortName::B) != 0) { *getPortReg<PortName::B>(offset) = mask(PortName::B); }
298+
%% for port in ports
299+
if constexpr (mask(PortName::{{port}})) { *getPortReg<PortName::{{port}}>(offset) = mask(PortName::{{port}}); }
300+
%% endfor
314301
}
315302

316303
template<PortName port>
317304
inline static constexpr uint32_t
318305
readPortReg(size_t offset)
319306
{
320-
if constexpr (port == PortName::A)
321-
{
322-
static_assert(mask(PortName::A) != 0,
323-
"Trying to read port which is not in the GpioSet!");
324-
return *getPortReg<PortName::A>(offset) & mask(PortName::A);
325-
} else if constexpr (port == PortName::B)
307+
%% for port in ports
308+
if constexpr (port == PortName::{{port}})
326309
{
327-
static_assert(mask(PortName::B) != 0,
328-
"Trying to read port which is not in the GpioSet!");
329-
return *getPortReg<PortName::B>(offset) & mask(PortName::B);
310+
static_assert(mask(PortName::{{port}}), "Trying to read port which is not in the GpioSet!");
311+
return *getPortReg<PortName::{{port}}>(offset) & mask(PortName::{{port}});
330312
}
313+
%% endfor
331314
}
332315

333316
public:
@@ -428,7 +411,7 @@ public:
428411
inline static bool
429412
read()
430413
{
431-
%% if target["family"] in ["g"]
414+
%% if target["family"] in ["g", "v"]
432415
return Base::readPortReg<PinConfig::port>(PIO_PDSR_OFFSET);
433416
%% else
434417
return Base::readPortReg<PinConfig::port>(PORT_IN_OFFSET);
@@ -491,13 +474,12 @@ struct Gpio<PinConfig>::As : public Gpio<PinConfig>
491474
inline static void
492475
connect()
493476
{
494-
%% if target["family"] in ["g"]
477+
%% if target["family"] in ["g", "v"]
495478
Pio* PIOBase;
496-
if constexpr (PinConfig::port == PortName::A) {
497-
PIOBase = PIOA;
498-
} else {
499-
PIOBase = PIOB;
500-
}
479+
%% for port in ports
480+
if constexpr (PinConfig::port == PortName::{{ port }})
481+
PIOBase = PIO{{ port }};
482+
%% endfor
501483
PIOBase->PIO_PDR = (1<<PinConfig::pin);
502484
Base::PinMux::set((uint32_t)PinSignal::function);
503485
%% else

0 commit comments

Comments
 (0)