48 lines
1.3 KiB
C++
48 lines
1.3 KiB
C++
|
#include "sunxi_d1_pinctrl/sunxi_d1_pinctrl.h"
|
||
|
|
||
|
namespace drivers {
|
||
|
namespace sunxi_d1_pinctrl {
|
||
|
|
||
|
SunxiD1Pinctrl::SunxiD1Pinctrl(void * const addr) :
|
||
|
m_registers(*reinterpret_cast<Registers *>(addr)) {}
|
||
|
|
||
|
void SunxiD1Pinctrl::set_pin_mode(
|
||
|
const Bank bank,
|
||
|
const uint8_t pin,
|
||
|
const uint8_t mode) {
|
||
|
// Config banks are split up every 8 GPIO pins
|
||
|
// Each bank is 32 bits and configures up to 8 pins
|
||
|
const int config_bank = pin / 8;
|
||
|
// Each config is 4 bits per pin
|
||
|
const int shift_amount = pin % 8 * 4;
|
||
|
const uint32_t mask = 0b1111 << shift_amount;
|
||
|
|
||
|
auto config = m_registers.ports[bank].config[config_bank];
|
||
|
config &= ~mask;
|
||
|
config |= (mode & 0b1111) << shift_amount;
|
||
|
m_registers.ports[bank].config[config_bank] = config;
|
||
|
}
|
||
|
|
||
|
void SunxiD1Pinctrl::set_pin_state(
|
||
|
const Bank bank,
|
||
|
const uint8_t pin,
|
||
|
const bool state) {
|
||
|
const uint32_t mask = 0b1 << pin;
|
||
|
|
||
|
auto data = m_registers.ports[bank].data;
|
||
|
if(state)
|
||
|
data |= mask;
|
||
|
else
|
||
|
data &= ~mask;
|
||
|
m_registers.ports[bank].data = data;
|
||
|
}
|
||
|
|
||
|
bool SunxiD1Pinctrl::get_pin_state(
|
||
|
const Bank bank,
|
||
|
const uint8_t pin) {
|
||
|
return m_registers.ports[bank].data >> pin & 1;
|
||
|
}
|
||
|
|
||
|
} // End namespace sunxi_d1_pinctrl
|
||
|
} // End namespace drivers
|