Skip to content

Commit 1e7c8b5

Browse files
committed
mb9bf650l gpio driver WIP
1 parent d1de115 commit 1e7c8b5

File tree

2 files changed

+162
-1
lines changed

2 files changed

+162
-1
lines changed

targets/chip/mb9bf566k/io/port.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <cstdint>
55
#include <cstddef>
66

7-
#include <klib/klib.hpp>
7+
#include <targets/core/cypress/mb9bf560l/port.hpp>
88

99
// global peripherals, not affected by chip package
1010
namespace klib::mb9bf566k::io::periph {
@@ -108,4 +108,17 @@ namespace klib::mb9bf566k::io::periph {
108108
};
109109
}
110110

111+
namespace klib::mb9bf566k::io::detail::pins {
112+
using namespace klib::core::mb9bf560l::io::detail::pins;
113+
}
114+
115+
namespace klib::mb9bf566k::io {
116+
template <typename Pin>
117+
using pin_in = klib::core::mb9bf560l::io::pin_in<Pin>;
118+
119+
template <typename Pin>
120+
using pin_out = klib::core::mb9bf560l::io::pin_out<Pin>;
121+
}
122+
123+
111124
#endif
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#ifndef KLIB_CYPRESS_MB9BF560L_PORT_HPP
2+
#define KLIB_CYPRESS_MB9BF560L_PORT_HPP
3+
4+
#include <cstdint>
5+
6+
#include <klib/klib.hpp>
7+
8+
namespace klib::core::mb9bf560l::io::detail::alternate {
9+
// alternate functions for all the gpio
10+
// default function (view reference manual for
11+
// default functions for every pin)
12+
struct none {};
13+
14+
// alternate function for analog pins
15+
struct analog {};
16+
}
17+
18+
namespace klib::core::mb9bf560l::io::detail::pins {
19+
// get the pin mask of a pin number
20+
template <typename Pin>
21+
constexpr uint32_t mask = 1U << Pin::number;
22+
23+
/**
24+
* @brief Helper function to set a pin to a specific peripheral
25+
*
26+
* @tparam Pin
27+
* @tparam Periph
28+
*/
29+
template <typename Pin, typename Periph>
30+
static void set_peripheral() {
31+
// check if we have a analog pin
32+
constexpr static bool has_analog = requires() {
33+
// if we have a analog number we have a analog pin
34+
(void)Pin::analog_number;
35+
};
36+
37+
// make sure we are not setting a pin that does not have
38+
// analog to analog
39+
static_assert(
40+
!std::is_same_v<Periph, io::detail::alternate::analog> ||
41+
(std::is_same_v<Periph, io::detail::alternate::analog> && has_analog),
42+
"Pin does not support analog"
43+
);
44+
45+
// always disable analog mode if we are not switching to analog mode
46+
if (!std::is_same_v<Periph, io::detail::alternate::analog>) {
47+
// disable the analog mode if it is available on the pin
48+
if constexpr (has_analog) {
49+
// disable the analog mode
50+
Pin::port::port->ADE &= (~detail::pins::mask<Pin>);
51+
}
52+
}
53+
54+
// get the pointer to the pin select we need to write to
55+
volatile uint32_t *const pfr = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->PFR0));
56+
57+
// set the alternate function
58+
if constexpr (std::is_same_v<Periph, io::detail::alternate::none>) {
59+
// enable control using the PIO. Disables peripheral
60+
// control of the pin
61+
pfr[Pin::port::id] &= (~detail::pins::mask<Pin>);
62+
}
63+
else if constexpr (std::is_same_v<Periph, io::detail::alternate::analog>) {
64+
// set the pin to analog mode
65+
Pin::port::port->ADE |= detail::pins::mask<Pin>;
66+
}
67+
}
68+
}
69+
70+
namespace klib::core::mb9bf560l::io {
71+
template <typename Pin>
72+
class pin_in {
73+
public:
74+
constexpr static void init() {
75+
// clear all the alternate functions
76+
detail::pins::set_peripheral<Pin, io::detail::alternate::none>();
77+
78+
// get the pointer to the pin select we need to write to
79+
volatile uint32_t *const ddr = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->DDR0));
80+
81+
// disable the output on the pin
82+
ddr[Pin::port::id] &= (~detail::pins::mask<Pin>);
83+
}
84+
85+
constexpr static bool get() {
86+
// get the pointer to the pin select we need to write to
87+
volatile uint32_t *const pdir = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->PDIR0));
88+
89+
// get the status of the pin
90+
return pdir[Pin::port::id] & detail::pins::mask<Pin>;
91+
}
92+
93+
template <bool Val>
94+
constexpr static void pullup_enable() {
95+
// get the pointer to the pin select we need to write to
96+
volatile uint32_t *const pcr = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->PCR0));
97+
98+
if constexpr (Val) {
99+
pcr[Pin::port::id] |= detail::pins::mask<Pin>;
100+
}
101+
else {
102+
pcr[Pin::port::id] &= (~detail::pins::mask<Pin>);
103+
}
104+
}
105+
};
106+
107+
template <typename Pin>
108+
class pin_out {
109+
public:
110+
constexpr static void init() {
111+
// clear all the alternate functions
112+
detail::pins::set_peripheral<Pin, io::detail::alternate::none>();
113+
114+
// get the pointer to the pin select we need to write to
115+
volatile uint32_t *const ddr = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->DDR0));
116+
117+
// // enable the gpio output
118+
ddr[Pin::port::id] |= detail::pins::mask<Pin>;
119+
}
120+
121+
template <bool Val>
122+
constexpr static void set() {
123+
// get the pointer to the pin select we need to write to
124+
volatile uint32_t *const pdor = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->PDOR0));
125+
126+
if constexpr (Val) {
127+
pdor[Pin::port::id] |= detail::pins::mask<Pin>;
128+
}
129+
else {
130+
pdor[Pin::port::id] &= (~detail::pins::mask<Pin>);
131+
}
132+
}
133+
134+
constexpr static void set(const bool val) {
135+
// get the pointer to the pin select we need to write to
136+
volatile uint32_t *const pdor = (reinterpret_cast<volatile uint32_t *const>(Pin::port::port->PDOR0));
137+
138+
if (val) {
139+
pdor[Pin::port::id] |= detail::pins::mask<Pin>;
140+
}
141+
else {
142+
pdor[Pin::port::id] &= (~detail::pins::mask<Pin>);
143+
}
144+
}
145+
};
146+
}
147+
148+
#endif

0 commit comments

Comments
 (0)