diff --git a/.gitignore b/.gitignore index 31a7fb773..788fe3395 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,5 @@ xcuserdata src/fppd.xcodeproj/project.xcworkspace/xcshareddata *-workspace .DS_Store +capes/drivers/bb64/pinctrl + diff --git a/LICENSE b/LICENSE index 85ddd78a0..35ab860fb 100644 --- a/LICENSE +++ b/LICENSE @@ -78,8 +78,13 @@ CC-BY-ND Components (see LICENSE.CC-BY-ND) - src/non-gpl/capeutils/CapeUtils.cpp - src/non-gpl/BBB48String/BBB48Strings.h - src/non-gpl/BBB48String/BBB48Strings.cpp + - src/non-gpl/BBB48String/*.asm + - src/non-gpl/BBShiftString/BBShiftString.h + - src/non-gpl/BBShiftString/BBShiftString.cpp + - src/non-gpl/BBShiftString/*.asm - src/non-gpl/DPIPixels/DPIPixels.h - src/non-gpl/DPIPixels/DPIPixels.cpp + - src/non-gpl/FalconV5Support/* The Falcon Player developers, Dan Kulp and Chris Pinkham, retain sole Copyright to all files under the non-gpl directory structure diff --git a/capes/drivers/bb64/Makefile b/capes/drivers/bb64/Makefile new file mode 100644 index 000000000..5388aad01 --- /dev/null +++ b/capes/drivers/bb64/Makefile @@ -0,0 +1,16 @@ + +%.o: %.cpp + ccache g++ -O3 -std=gnu++23 -c $(SRCDIR)$< -o $@ + +pinctrl: src/AM6232.o src/Ball.o src/PocketBeagle2.o src/ConfigPin.o src/Pin.o + g++ -o pinctrl src/AM6232.o src/Ball.o src/PocketBeagle2.o src/ConfigPin.o src/Pin.o + chmod +s pinctrl + +install: pinctrl + cp -f pinctrl /usr/bin + chmod +s /usr/bin/pinctrl + +clean: + rm -f pinctrl src/*.o + +all: pinctrl \ No newline at end of file diff --git a/capes/drivers/bb64/src/AM6232.cpp b/capes/drivers/bb64/src/AM6232.cpp new file mode 100644 index 000000000..811d7983c --- /dev/null +++ b/capes/drivers/bb64/src/AM6232.cpp @@ -0,0 +1,154 @@ + + +#include "Ball.h" + +std::map AM6232ALW; + +#define PULLUDEN_SHIFT (16) +#define PULLTYPESEL_SHIFT (17) +#define RXACTIVE_SHIFT (18) +#define DEBOUNCE_SHIFT (11) +#define WKUP_EN_SHIFT (29) + +#define PULL_DISABLE (1 << PULLUDEN_SHIFT) +#define PULL_ENABLE (0 << PULLUDEN_SHIFT) + +#define PULL_UP (1 << PULLTYPESEL_SHIFT | PULL_ENABLE) +#define PULL_DOWN (0 << PULLTYPESEL_SHIFT | PULL_ENABLE) + +#define INPUT_EN (1 << RXACTIVE_SHIFT) +#define INPUT_DISABLE (0 << RXACTIVE_SHIFT) + +#define PIN_OUTPUT (INPUT_DISABLE | PULL_DISABLE) +#define PIN_OUTPUT_PULLUP (INPUT_DISABLE | PULL_UP) +#define PIN_OUTPUT_PULLDOWN (INPUT_DISABLE | PULL_DOWN) +#define PIN_INPUT (INPUT_EN | PULL_DISABLE) +#define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) +#define PIN_INPUT_PULLDOWN (INPUT_EN | PULL_DOWN) + +constexpr uint32_t MCU_DOMAIN = 0; +constexpr uint32_t MAIN_DOMAIN = 1; + +static Ball& addBall(const std::string& n, uint32_t d, uint32_t o, bool addGPIO = true, uint32_t pru0Base = 0xFFFFFFFF, uint32_t pru1Base = 0xFFFFFFFF) { + Ball& b = Ball::addBall(n, d, o); + b.addMode("reset", { 0x8214007 }); + if (addGPIO) { + b.addMode("gpio", { PIN_INPUT | 7 }).addMode("gpio_pu", { PIN_INPUT_PULLUP | 7 }).addMode("gpio_pd", { PIN_INPUT_PULLDOWN | 7 }).addMode("gpio_out", { PIN_OUTPUT | 7 }); + } + if (pru0Base < 0xFF) { + b.addMode("pruout", { PIN_OUTPUT | pru1Base }).addMode("pruin", { PIN_INPUT | (pru1Base + 1) }).addMode("pru0out", { PIN_OUTPUT | pru1Base }).addMode("pru0in", { PIN_INPUT | (pru1Base + 1) }); + } + if (pru1Base < 0xFF) { + if (pru0Base >= 0xFF) { + b.addMode("pruout", { PIN_OUTPUT | pru1Base }).addMode("pruin", { PIN_INPUT | (pru1Base + 1) }); + } + b.addMode("pru1out", { PIN_OUTPUT | pru1Base }).addMode("pru1in", { PIN_INPUT | (pru1Base + 1) }); + } + return b; +} + +void InitAM6232Balls() { + addBall("A18", MAIN_DOMAIN, 0x1F0); + addBall("L23", MAIN_DOMAIN, 0x084); + addBall("P25", MAIN_DOMAIN, 0x07C); + addBall("M22", MAIN_DOMAIN, 0x0A4, true, 4); + addBall("L24", MAIN_DOMAIN, 0x088); + addBall("L25", MAIN_DOMAIN, 0x08C); + addBall("K25", MAIN_DOMAIN, 0x0A0); + addBall("M25", MAIN_DOMAIN, 0x03C); + addBall("N23", MAIN_DOMAIN, 0x040); + addBall("N24", MAIN_DOMAIN, 0x044); + addBall("N25", MAIN_DOMAIN, 0x048); + addBall("P24", MAIN_DOMAIN, 0x04C); + addBall("P22", MAIN_DOMAIN, 0x050); + addBall("P21", MAIN_DOMAIN, 0x054); + addBall("R23", MAIN_DOMAIN, 0x058); + addBall("R24", MAIN_DOMAIN, 0x05C); + addBall("R25", MAIN_DOMAIN, 0x060); + addBall("T25", MAIN_DOMAIN, 0x064); + addBall("R21", MAIN_DOMAIN, 0x068); + addBall("T22", MAIN_DOMAIN, 0x06C); + addBall("T24", MAIN_DOMAIN, 0x070); + addBall("U25", MAIN_DOMAIN, 0x074); + addBall("U24", MAIN_DOMAIN, 0x078); + addBall("M24", MAIN_DOMAIN, 0x090); + addBall("N20", MAIN_DOMAIN, 0x094); + addBall("M21", MAIN_DOMAIN, 0x0A8); + addBall("L21", MAIN_DOMAIN, 0x0AC); + addBall("K22", MAIN_DOMAIN, 0x0B0); + addBall("K24", MAIN_DOMAIN, 0x0B4); + addBall("U23", MAIN_DOMAIN, 0x098); + addBall("V25", MAIN_DOMAIN, 0x09C); + addBall("B16", MAIN_DOMAIN, 0x1E0); + addBall("A16", MAIN_DOMAIN, 0x1E4); + addBall("B17", MAIN_DOMAIN, 0x1E8); + addBall("A17", MAIN_DOMAIN, 0x1EC); + addBall("E15", MAIN_DOMAIN, 0x1DC, true).addMode("uart5_tx", { PIN_OUTPUT | 1 }).addMode("can0_rx", { PIN_INPUT | 0 }); + addBall("C15", MAIN_DOMAIN, 0x1D8, true).addMode("uart5_rx", { PIN_INPUT | 1 }).addMode("can0_tx", { PIN_OUTPUT | 0 }); + addBall("A20", MAIN_DOMAIN, 0x1B0); + addBall("B20", MAIN_DOMAIN, 0x1A4); + addBall("E19", MAIN_DOMAIN, 0x1AC); + addBall("D20", MAIN_DOMAIN, 0x1A8); + addBall("E18", MAIN_DOMAIN, 0x1A0); + addBall("B18", MAIN_DOMAIN, 0x19C); + addBall("A19", MAIN_DOMAIN, 0x198); + addBall("B19", MAIN_DOMAIN, 0x194); + addBall("D1", MCU_DOMAIN, 0x060); + addBall("A8", MCU_DOMAIN, 0x044); + addBall("D10", MCU_DOMAIN, 0x048); + addBall("B3", MCU_DOMAIN, 0x038); + addBall("D6", MCU_DOMAIN, 0x034); + addBall("D4", MCU_DOMAIN, 0x040); + addBall("E5", MCU_DOMAIN, 0x03C); + addBall("B5", MCU_DOMAIN, 0x014); + addBall("A5", MCU_DOMAIN, 0x018); + addBall("AD24", MAIN_DOMAIN, 0x160); + addBall("AB22", MAIN_DOMAIN, 0x15C); + addBall("AD23", MAIN_DOMAIN, 0x180); + addBall("AD22", MAIN_DOMAIN, 0x17C); + addBall("AE21", MAIN_DOMAIN, 0x168); + addBall("AA19", MAIN_DOMAIN, 0x164); + addBall("AE23", MAIN_DOMAIN, 0x184); + addBall("AB20", MAIN_DOMAIN, 0x188); + addBall("AC21", MAIN_DOMAIN, 0x18C); + addBall("AE22", MAIN_DOMAIN, 0x190); + addBall("Y18", MAIN_DOMAIN, 0x16C); + addBall("AA18", MAIN_DOMAIN, 0x170, true, 0xFFFF, 3); + addBall("AD21", MAIN_DOMAIN, 0x174, true, 0xFFFF, 3); + addBall("AC20", MAIN_DOMAIN, 0x178); + addBall("A14", MAIN_DOMAIN, 0x1BC); + addBall("A13", MAIN_DOMAIN, 0x1B4); + addBall("C13", MAIN_DOMAIN, 0x1B8); + addBall("B13", MAIN_DOMAIN, 0x1C0); + addBall("B14", MAIN_DOMAIN, 0x1C4); + addBall("A15", MAIN_DOMAIN, 0x1D0, true).addMode("uart2_rx", { PIN_INPUT | 3 }); + addBall("B15", MAIN_DOMAIN, 0x1D4, true).addMode("uart3_tx", { PIN_OUTPUT | 3 }); + addBall("D14", MAIN_DOMAIN, 0x1C8); + addBall("E14", MAIN_DOMAIN, 0x1CC); + addBall("F18", MAIN_DOMAIN, 0x258); + addBall("Y20", MAIN_DOMAIN, 0x0FC); + addBall("AB24", MAIN_DOMAIN, 0x0F8); + addBall("AC24", MAIN_DOMAIN, 0x104, true, 5, 2); + addBall("AC25", MAIN_DOMAIN, 0x100, true, 5, 2); + addBall("U22", MAIN_DOMAIN, 0x0B8); + addBall("V24", MAIN_DOMAIN, 0x0BC); + addBall("W25", MAIN_DOMAIN, 0xC0, true, 5, 2).addMode("uart3_rx", { PIN_INPUT | 4 }); + addBall("W24", MAIN_DOMAIN, 0x0C4, true, 5, 2); + addBall("Y25", MAIN_DOMAIN, 0x0C8); + addBall("Y24", MAIN_DOMAIN, 0x0CC); + addBall("Y23", MAIN_DOMAIN, 0x0D0); + addBall("AA25", MAIN_DOMAIN, 0x0D4, true, 5, 2).addMode("uart5_tx", { PIN_OUTPUT | 4 }); + addBall("V21", MAIN_DOMAIN, 0x0D8, true, 5, 2).addMode("uart6_rx", { PIN_INPUT | 4 }); + addBall("W21", MAIN_DOMAIN, 0x0DC, true, 5, 2); + addBall("V20", MAIN_DOMAIN, 0x0E0); + addBall("AA23", MAIN_DOMAIN, 0x0E4); + addBall("AB25", MAIN_DOMAIN, 0x0E8); + addBall("AA24", MAIN_DOMAIN, 0x0EC, true, 5, 2); + addBall("Y22", MAIN_DOMAIN, 0x0F0); + addBall("AA21", MAIN_DOMAIN, 0x0F4, true, 5, 2); + addBall("AE18", MAIN_DOMAIN, 0x13C); + addBall("AD18", MAIN_DOMAIN, 0x140); + + addBall("B9", MCU_DOMAIN, 0x04C); + addBall("A9", MCU_DOMAIN, 0x050); +} \ No newline at end of file diff --git a/capes/drivers/bb64/src/Ball.cpp b/capes/drivers/bb64/src/Ball.cpp new file mode 100644 index 000000000..5fdd90039 --- /dev/null +++ b/capes/drivers/bb64/src/Ball.cpp @@ -0,0 +1,57 @@ +#include + +#include "Ball.h" + +static std::map BALLS; +static std::map DOMAINS; + +Ball& Ball::addBall(const std::string& n, uint32_t d, uint32_t o) { + return BALLS[n].set(n, d, o); +} +Ball& Ball::findBall(const std::string& n) { + return BALLS[n]; +} +void Ball::setDomainAddress(uint32_t d, uint8_t* ad) { + DOMAINS[d] = ad; +} + +Ball& Ball::query() { + if (offset) { + uint8_t* d = DOMAINS[domain]; + d += offset; + uint32_t* v = (uint32_t*)d; + printf("\t%s: %X", name.c_str(), *v); + for (auto& m : modesetCommands) { + if (!m.second.empty() && m.second.back() == *v) { + printf(" %s", m.first.c_str()); + } + } + printf("\n"); + } + return *this; +} +std::string Ball::queryMode() { + if (offset) { + uint8_t* d = DOMAINS[domain]; + d += offset; + uint32_t* v = (uint32_t*)d; + for (auto& m : modesetCommands) { + if (!m.second.empty() && m.second.back() == *v && m.first != "reset") { + return m.first; + } + } + } + return ""; +} + +Ball& Ball::setMode(const std::string& m) { + auto& c = modesetCommands[m]; + uint8_t* d = DOMAINS[domain]; + d += offset; + uint32_t* v = (uint32_t*)d; + for (auto& cmd : c) { + *v = cmd; + std::this_thread::yield(); + } + return *this; +} diff --git a/capes/drivers/bb64/src/Ball.h b/capes/drivers/bb64/src/Ball.h new file mode 100644 index 000000000..8afc6c8c5 --- /dev/null +++ b/capes/drivers/bb64/src/Ball.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include + +class Ball { +public: + Ball() {} + Ball(uint32_t d, uint32_t o) : + domain(d), offset(o) {} + Ball(const std::string& n, uint32_t d, uint32_t o) : + name(n), domain(d), offset(o) {} + + Ball& set(const std::string& n, uint32_t d, uint32_t o) { + name = n; + domain = d; + offset = o; + return *this; + } + + Ball& addMode(const std::string& n, const std::vector& c) { + modesetCommands.emplace(n, c); + return *this; + } + + std::string queryMode(); + Ball& query(); + Ball& setMode(const std::string& m); + + std::string name; + uint32_t domain = 0; + uint32_t offset = 0; + + std::map> modesetCommands; + + static Ball& addBall(const std::string& n, uint32_t d, uint32_t o); + static Ball& findBall(const std::string& n); + + static void setDomainAddress(uint32_t d, uint8_t* ad); +}; \ No newline at end of file diff --git a/capes/drivers/bb64/src/ConfigPin.cpp b/capes/drivers/bb64/src/ConfigPin.cpp new file mode 100644 index 000000000..108760d5c --- /dev/null +++ b/capes/drivers/bb64/src/ConfigPin.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "Ball.h" +#include "Pin.h" + +constexpr uint64_t MEMLOCATIONS[] = { 0x4084000, 0xf4000, 0x0 }; +constexpr uint64_t MAX_OFFSET = 0x260; + +extern void InitPocketBeagle2(); + +extern "C" { +int main(int argc, char const* argv[]) { + InitPocketBeagle2(); + + int mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + int d = 0; + while (MEMLOCATIONS[d]) { + uint8_t* gpio_map = (uint8_t*)mmap( + NULL, /* Any address in our space will do */ + MAX_OFFSET, /* Map length */ + PROT_READ | PROT_WRITE, /* Enable reading & writing */ + MAP_SHARED, /* Shared with other processes */ + mem_fd, /* File to map */ + MEMLOCATIONS[d] /* Offset to GPIO peripheral */ + ); + Ball::setDomainAddress(d, gpio_map); + ++d; + } + close(mem_fd); + + std::string arg1(argv[1]); + if (arg1 == "-q") { + if (argc > 2) { + Pin::getPin(argv[2]).query(); + } else { + for (auto& p : Pin::getAllPins()) { + printf("%s: \n", p.first.c_str()); + p.second.query(); + } + } + } else if (arg1 == "-s") { + Pin::getPin(argv[2]).setMode(argv[3]); + } else if (arg1 == "-l") { + if (argc > 2) { + Pin::getPin(argv[2]).listModes(); + } else { + for (auto& p : Pin::getAllPins()) { + printf("%s: ", p.first.c_str()); + p.second.listModes(); + } + } + } + return 0; +} +} diff --git a/capes/drivers/bb64/src/Pin.cpp b/capes/drivers/bb64/src/Pin.cpp new file mode 100644 index 000000000..c07e41ed5 --- /dev/null +++ b/capes/drivers/bb64/src/Pin.cpp @@ -0,0 +1,72 @@ +#include "Pin.h" +#include "Ball.h" + +static std::map PINS; + +Pin& Pin::addPin(const std::string& n) { + PINS.emplace(n, n); + return PINS[n]; +} +Pin& Pin::getPin(const std::string& n) { + return PINS[n]; +} + +const std::map& Pin::getAllPins() { + return PINS; +} + +const Pin& Pin::query() const { + for (auto& b : balls) { + Ball::findBall(b).query(); + } + return *this; +} +const Pin& Pin::listModes() const { + std::string qm = ""; + for (auto& b : balls) { + std::string bm = Ball::findBall(b).queryMode(); + if (!bm.empty()) { + qm = bm; + break; + } + } + + for (const auto& md : modes) { + if (md.first == qm) { + printf("[%s] ", md.first.c_str()); + } else { + printf("%s ", md.first.c_str()); + } + } + printf("\n"); + return *this; +} + +const Pin& Pin::setMode(const std::string& m) const { + const auto& md = modes.find(m); + if (md != modes.end()) { + // first, reset the "other" balls so they go into input mode + for (auto& b : balls) { + if (b != md->second.first) { + Ball::findBall(b).setMode("reset"); + } + } + // now set the target mode + auto& b = Ball::findBall(md->second.first); + b.setMode("reset"); + b.setMode(md->second.second); + } else { + printf("Unknown mode for pin %s: %s\n", name.c_str(), m.c_str()); + } + return *this; +} +Pin& Pin::modesFromBall(const std::string& b) { + std::string bn = b.empty() ? balls.front() : b; + auto& ball = Ball::findBall(bn); + for (auto& m : ball.modesetCommands) { + if (m.first != "reset") { + addMode(m.first, bn, m.first); + } + } + return *this; +} diff --git a/capes/drivers/bb64/src/Pin.h b/capes/drivers/bb64/src/Pin.h new file mode 100644 index 000000000..2b1bd2ca2 --- /dev/null +++ b/capes/drivers/bb64/src/Pin.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +class Pin { +public: + Pin() = default; + + Pin(const std::string& n) : + name(n) {} + + std::string name; + + Pin& addBall(const std::string& n) { + balls.emplace_back(n); + return *this; + } + Pin& addMode(const std::string& m, const std::string& b, const std::string& bm) { + modes[m] = { b, bm }; + return *this; + } + Pin& modesFromBall(const std::string& b = ""); + + const Pin& query() const; + const Pin& listModes() const; + const Pin& setMode(const std::string& m) const; + + std::list balls; + std::map> modes; + + static Pin& addPin(const std::string& n); + static Pin& getPin(const std::string& n); + static const std::map& getAllPins(); +}; diff --git a/capes/drivers/bb64/src/PocketBeagle2.cpp b/capes/drivers/bb64/src/PocketBeagle2.cpp new file mode 100644 index 000000000..dc5d8008d --- /dev/null +++ b/capes/drivers/bb64/src/PocketBeagle2.cpp @@ -0,0 +1,73 @@ + + +#include "Ball.h" +#include "Pin.h" + +extern void InitAM6232Balls(); + +void InitPocketBeagle2() { + InitAM6232Balls(); + + Pin::addPin("P1_02").addBall("E18").addBall("E18").addBall("AA19"); + Pin::addPin("P1_03").addBall("F18"); + Pin::addPin("P1_04").addBall("Y18").addBall("D20"); + Pin::addPin("P1_06").addBall("E19").addBall("AD18"); + Pin::addPin("P1_08").addBall("A20"); + Pin::addPin("P1_10").addBall("A18").addBall("B19"); + Pin::addPin("P1_12").addBall("A19").addBall("AE18"); + Pin::addPin("P1_13").addBall("N20"); + Pin::addPin("P1_19").addBall("AD22"); + Pin::addPin("P1_20").addBall("Y24"); + Pin::addPin("P1_21").addBall("AE22"); + Pin::addPin("P1_23").addBall("AC21"); + Pin::addPin("P1_25").addBall("AB20"); + Pin::addPin("P1_26").addBall("D6").addBall("K24"); + Pin::addPin("P1_27").addBall("AE23"); + Pin::addPin("P1_28").addBall("B3").addBall("K22"); + Pin::addPin("P1_29").addBall("Y20"); + Pin::addPin("P1_30").addBall("E14"); + Pin::addPin("P1_31").addBall("Y22"); + Pin::addPin("P1_32").addBall("D14"); + Pin::addPin("P1_33").addBall("A17").addBall("AA23"); + Pin::addPin("P1_34").addBall("AD23"); + Pin::addPin("P1_35").addBall("AE21"); + Pin::addPin("P1_36").addBall("V20").addBall("B17"); + + Pin::addPin("P2_01").addBall("AD24").addBall("B20"); + Pin::addPin("P2_02").addBall("U22"); + Pin::addPin("P2_03").addBall("AB22").addBall("B18"); + Pin::addPin("P2_04").addBall("V24"); + Pin::addPin("P2_05").addBall("C15").addBall("B5").modesFromBall("C15").addMode("uart", "C15", "uart5_rx"); + Pin::addPin("P2_06").addBall("W25").modesFromBall(); + Pin::addPin("P2_07").addBall("E15").addBall("A5").modesFromBall("E15").addMode("uart", "E15", "uart5_tx"); + Pin::addPin("P2_08").addBall("W24").modesFromBall(); + Pin::addPin("P2_09").addBall("A15").addBall("D4").modesFromBall("A15"); + Pin::addPin("P2_10").addBall("AD21").modesFromBall(); + Pin::addPin("P2_11").addBall("B15").addBall("E5").modesFromBall("B15"); + Pin::addPin("P2_17").addBall("AC24").modesFromBall(); + Pin::addPin("P2_18").addBall("V21").modesFromBall(); + Pin::addPin("P2_19").addBall("AC20"); + Pin::addPin("P2_20").addBall("Y25"); + Pin::addPin("P2_22").addBall("AC25").modesFromBall(); + Pin::addPin("P2_24").addBall("Y23"); + Pin::addPin("P2_25").addBall("B14"); + Pin::addPin("P2_27").addBall("B13"); + Pin::addPin("P2_28").addBall("AB24"); + Pin::addPin("P2_29").addBall("M22").addBall("A14").modesFromBall("M22"); + Pin::addPin("P2_30").addBall("AA24").modesFromBall(); + Pin::addPin("P2_31").addBall("AA18").addBall("A13").modesFromBall("AA18"); + Pin::addPin("P2_32").addBall("AB25"); + Pin::addPin("P2_33").addBall("AA25").modesFromBall().addMode("uart", "AA25", "uart5_tx"); + Pin::addPin("P2_34").addBall("AA21").modesFromBall(); + Pin::addPin("P2_35").addBall("W21").modesFromBall(); + Pin::addPin("P2_36").addBall("C13"); + + /* + Pin::addPin("I2C0_SCL").addBall("B16"); + Pin::addPin("I2C0_SDA").addBall("A16"); + Pin::addPin("WKUP_I2C0_SCL").addBall("B9"); + Pin::addPin("WKUP_I2C0_SDA").addBall("A9"); + Pin::addPin("I2C1_SCL").addBall("B17"); + Pin::addPin("I2C1_SDA").addBall("A17"); + */ +} diff --git a/src/util/BBBPruUtils.cpp b/src/util/BBBPruUtils.cpp index 7f06e6d67..c87a973bd 100644 --- a/src/util/BBBPruUtils.cpp +++ b/src/util/BBBPruUtils.cpp @@ -35,8 +35,6 @@ static unsigned int proc_read(const char* const fname) { return x; } -static bool hasUIO = true; - class PRUCoreInfo { public: int pru_num = 0; @@ -47,44 +45,27 @@ class PRUCoreInfo { uint32_t sharedRamPhyLoc = 0; int sharedRamSize = 0; - uint8_t* instructionRam = nullptr; - int instructionRamSize = 0; - - unsigned int* controlRegs = nullptr; - void disable() { - if (!hasUIO) { - std::string filename = "/sys/class/remoteproc/remoteproc" + std::to_string(pru_num) + "/state"; - if (FileExists(filename)) { - FILE* rp = fopen(filename.c_str(), "w"); - fprintf(rp, "stop"); - fclose(rp); - } - } else { - controlRegs[0] = 1; + std::string filename = "/sys/class/remoteproc/remoteproc" + std::to_string(pru_num) + "/state"; + if (FileExists(filename)) { + FILE* rp = fopen(filename.c_str(), "w"); + fprintf(rp, "stop"); + fclose(rp); } } void enable(uint32_t addr = 0) { - if (!hasUIO) { - std::string filename = "/sys/class/remoteproc/remoteproc" + std::to_string(pru_num) + "/state"; - int cnt = 0; - while (!FileExists(filename) && cnt < 20000) { - cnt++; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - if (FileExists(filename) && cnt < 20000) { - FILE* rp = fopen(filename.c_str(), "w"); - fprintf(rp, "start"); - fclose(rp); - } else { - LogWarn(VB_CHANNELOUT, "BBBPru::Pru::enable() - could not start PRU core %d\n", pru_num); - } + std::string filename = "/sys/class/remoteproc/remoteproc" + std::to_string(pru_num) + "/state"; + int cnt = 0; + while (!FileExists(filename) && cnt < 10000) { + cnt++; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + if (FileExists(filename) && cnt < 10000) { + FILE* rp = fopen(filename.c_str(), "w"); + fprintf(rp, "start"); + fclose(rp); } else { - uint32_t a = addr; - a /= sizeof(uint32_t); - a <<= 16; - a |= 2; - controlRegs[0] = a; + LogWarn(VB_CHANNELOUT, "BBBPru::Pru::enable() - could not start PRU core %d\n", pru_num); } } }; @@ -97,51 +78,71 @@ static size_t ddr_filelen = 0; static uint8_t* base_memory_location = nullptr; static PRUCoreInfo prus[2]; -#define AM33XX_PRU_BASE 0x4a300000 -#define AM33XX_PRUSS_MMAP_SIZE 0x40000 - -#define AM33XX_DATARAM0_PHYS_BASE 0x4a300000 -#define AM33XX_DATARAM1_PHYS_BASE 0x4a302000 -#define AM33XX_INTC_PHYS_BASE 0x4a320000 -#define AM33XX_PRU0CONTROL_PHYS_BASE 0x4a322000 -#define AM33XX_PRU0DEBUG_PHYS_BASE 0x4a322400 -#define AM33XX_PRU1CONTROL_PHYS_BASE 0x4a324000 -#define AM33XX_PRU1DEBUG_PHYS_BASE 0x4a324400 -#define AM33XX_PRU0IRAM_PHYS_BASE 0x4a334000 -#define AM33XX_PRU1IRAM_PHYS_BASE 0x4a338000 -#define AM33XX_PRUSS_SHAREDRAM_BASE 0x4a310000 -#define AM33XX_PRUSS_CFG_BASE 0x4a326000 -#define AM33XX_PRUSS_UART_BASE 0x4a328000 -#define AM33XX_PRUSS_IEP_BASE 0x4a32e000 -#define AM33XX_PRUSS_ECAP_BASE 0x4a330000 -#define AM33XX_PRUSS_MIIRT_BASE 0x4a332000 -#define AM33XX_PRUSS_MDIO_BASE 0x4a332400 +#if defined(PLATFORM_BBB) + +constexpr uintptr_t PRUSS_MMAP_BASE = 0x4a300000; +constexpr size_t PRUSS_MMAP_SIZE = 0x40000; + +constexpr uintptr_t PRUSS_DATARAM0_PHYS_BASE = 0x4a300000; +constexpr uintptr_t PRUSS_DATARAM1_PHYS_BASE = 0x4a302000; +constexpr size_t PRUSS_DATARAM_SIZE = 8 * 1024; // 8K + +constexpr uintptr_t PRUSS_SHAREDRAM_BASE = 0x4a310000; +constexpr size_t PRUSS_SHAREDRAM_SIZE = 12 * 1024; // 12K + +constexpr uintptr_t DDR_ADDR = 0x8f000000; +constexpr uintptr_t DDR_SIZE = 0x00400000; + +constexpr std::string FIRMWARE_PREFIX = "am335x"; +constexpr bool FAKE_PRU = false; + +#elif defined(PLATFORM_BB64) +constexpr uintptr_t PRUSS_MMAP_BASE = 0x30040000; +constexpr size_t PRUSS_MMAP_SIZE = 0x80000; + +constexpr size_t PRUSS_DATARAM_SIZE = 8 * 1024; // 8K +constexpr uintptr_t PRUSS_DATARAM0_PHYS_BASE = 0x30040000; +constexpr uintptr_t PRUSS_DATARAM1_PHYS_BASE = 0x30042000; + +constexpr uintptr_t PRUSS_SHAREDRAM_BASE = 0x30050000; +constexpr size_t PRUSS_SHAREDRAM_SIZE = 32 * 1024; // 32K + +// constexpr uintptr_t DDR_ADDR = 0x8f000000; +// constexpr uintptr_t DDR_SIZE = 0x00400000; + +constexpr uintptr_t DDR_ADDR = 0; +constexpr uintptr_t DDR_SIZE = 0x00400000; +constexpr std::string FIRMWARE_PREFIX = "am62x"; + +constexpr bool FAKE_PRU = true; +#endif static void initPrus() { const int mem_fd = open("/dev/mem", O_RDWR); - base_memory_location = (uint8_t*)mmap(0, - AM33XX_PRUSS_MMAP_SIZE, - PROT_WRITE | PROT_READ, - MAP_SHARED, - mem_fd, - AM33XX_PRU_BASE); + if (!FAKE_PRU) { + base_memory_location = (uint8_t*)mmap(0, + PRUSS_MMAP_SIZE, + PROT_WRITE | PROT_READ, + MAP_SHARED, + mem_fd, + PRUSS_MMAP_BASE); + } else { + base_memory_location = (uint8_t*)mmap(0, + PRUSS_MMAP_SIZE, + PROT_WRITE | PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + 0, + 0); + } - uintptr_t ddr_addr = 0x8f000000; - uintptr_t ddr_sizeb = 0x00400000; + uintptr_t ddr_addr = DDR_ADDR; + uintptr_t ddr_sizeb = DDR_SIZE; - if (FileExists("/sys/class/uio/uio0/maps/map1/addr")) { - hasUIO = true; - ddr_addr = proc_read("/sys/class/uio/uio0/maps/map1/addr"); - ddr_sizeb = proc_read("/sys/class/uio/uio0/maps/map1/size"); - ddr_filelen = ddr_sizeb; - } else { - hasUIO = false; - if (!FileExists("/sys/class/remoteproc/remoteproc0/state")) { - system("modprobe pru_rproc"); - } + if (!FileExists("/sys/class/remoteproc/remoteproc0/state")) { + system("modprobe pru_rproc"); } - if (ddr_mem_loc == nullptr) { + if (ddr_mem_loc == nullptr && ddr_addr) { ddr_phy_mem_loc = ddr_addr; ddr_filelen = ddr_sizeb; ddr_mem_loc = (uint8_t*)mmap(0, @@ -150,31 +151,37 @@ static void initPrus() { MAP_SHARED, mem_fd, ddr_addr); + } else if (ddr_addr == 0) { + // just malloc some memory so we don't crash + ddr_phy_mem_loc = ddr_addr; + ddr_filelen = ddr_sizeb; + ddr_mem_loc = (uint8_t*)mmap(0, + ddr_filelen, + PROT_WRITE | PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + 0, + 0); } close(mem_fd); prus[0].pru_num = 0; prus[1].pru_num = 1; - prus[0].controlRegs = (uint32_t*)(base_memory_location + (AM33XX_PRU0CONTROL_PHYS_BASE - AM33XX_PRU_BASE)); - prus[1].controlRegs = (uint32_t*)(base_memory_location + (AM33XX_PRU1CONTROL_PHYS_BASE - AM33XX_PRU_BASE)); - prus[0].dataRam = base_memory_location + (AM33XX_DATARAM0_PHYS_BASE - AM33XX_PRU_BASE); - prus[0].dataRamSize = 8 * 1024; - prus[0].dataRamPhyLoc = AM33XX_DATARAM0_PHYS_BASE; - prus[1].dataRam = base_memory_location + (AM33XX_DATARAM1_PHYS_BASE - AM33XX_PRU_BASE); - prus[1].dataRamSize = 8 * 1024; - prus[1].dataRamPhyLoc = AM33XX_DATARAM1_PHYS_BASE; - prus[0].sharedRam = base_memory_location + (AM33XX_PRUSS_SHAREDRAM_BASE - AM33XX_PRU_BASE); - prus[0].sharedRamSize = 12 * 1024; - prus[0].sharedRamPhyLoc = AM33XX_PRUSS_SHAREDRAM_BASE; - prus[1].sharedRam = base_memory_location + (AM33XX_PRUSS_SHAREDRAM_BASE - AM33XX_PRU_BASE); - prus[1].sharedRamSize = 12 * 1024; - prus[1].sharedRamPhyLoc = AM33XX_PRUSS_SHAREDRAM_BASE; - prus[0].instructionRam = base_memory_location + (AM33XX_PRU0IRAM_PHYS_BASE - AM33XX_PRU_BASE); - prus[0].instructionRamSize = 8 * 1024; - prus[1].instructionRam = base_memory_location + (AM33XX_PRU1IRAM_PHYS_BASE - AM33XX_PRU_BASE); - prus[1].instructionRamSize = 8 * 1024; - - memset(ddr_mem_loc, 0, ddr_sizeb); + prus[0].dataRam = base_memory_location + (PRUSS_DATARAM0_PHYS_BASE - PRUSS_MMAP_BASE); + prus[0].dataRamSize = PRUSS_DATARAM_SIZE; + prus[0].dataRamPhyLoc = PRUSS_DATARAM0_PHYS_BASE; + prus[1].dataRam = base_memory_location + (PRUSS_DATARAM1_PHYS_BASE - PRUSS_MMAP_BASE); + prus[1].dataRamSize = PRUSS_DATARAM_SIZE; + prus[1].dataRamPhyLoc = PRUSS_DATARAM1_PHYS_BASE; + prus[0].sharedRam = base_memory_location + (PRUSS_SHAREDRAM_BASE - PRUSS_MMAP_BASE); + prus[0].sharedRamSize = PRUSS_SHAREDRAM_SIZE; + prus[0].sharedRamPhyLoc = PRUSS_SHAREDRAM_BASE; + prus[1].sharedRam = base_memory_location + (PRUSS_SHAREDRAM_BASE - PRUSS_MMAP_BASE); + prus[1].sharedRamSize = PRUSS_SHAREDRAM_SIZE; + prus[1].sharedRamPhyLoc = PRUSS_SHAREDRAM_BASE; + + if (ddr_sizeb) { + memset(ddr_mem_loc, 0, ddr_sizeb); + } __asm__ __volatile__("" :: : "memory"); } @@ -218,7 +225,7 @@ BBBPru::~BBBPru() { ddr_mem_loc = nullptr; } if (base_memory_location) { - munmap(base_memory_location, AM33XX_PRUSS_MMAP_SIZE); + munmap(base_memory_location, PRUSS_MMAP_SIZE); base_memory_location = nullptr; } } @@ -227,72 +234,16 @@ BBBPru::~BBBPru() { int BBBPru::run(const std::string& program) { LogDebug(VB_CHANNELOUT, "BBBPru[%d]::run(%s)\n", pru_num, program.c_str()); - if (!hasUIO) { - LogDebug(VB_CHANNELOUT, "Using remoteproc: %s\n", program.c_str()); - prus[pru_num].disable(); - CopyFileContents(program, "/lib/firmware/am335x-pru" + std::to_string(pru_num) + "-fw"); - prus[pru_num].enable(); - - memset(prus[pru_num].dataRam, 0, prus[pru_num].dataRamSize); - memset(prus[pru_num].dataRam, 0, prus[pru_num].dataRamSize); - - return false; - } - - struct stat st; - stat(program.c_str(), &st); - size_t file_size = st.st_size; - uint32_t startOffset = 0; - int fhand = open(program.c_str(), O_RDWR); - uint8_t* buf = (uint8_t*)mmap(0, file_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fhand, 0); - close(fhand); - prus[pru_num].disable(); - if (buf[0] == ELFMAG0 && buf[1] == ELFMAG1 && buf[2] == ELFMAG2 && buf[3] == ELFMAG3) { - // elf linked unit - LogDebug(VB_CHANNELOUT, "Elf: %s\n", program.c_str()); - - if (buf[EI_CLASS] == ELFCLASS32) { - Elf32_Ehdr* hdr = (Elf32_Ehdr*)buf; - uint32_t saddress = hdr->e_entry; - Elf32_Phdr* phdr = (Elf32_Phdr*)&buf[hdr->e_phoff]; - for (int pn = 0; pn < hdr->e_phnum; pn++, phdr++) { - if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) { - // printf("Type: %d VA: %X OFF: %X SZ: %d\n", phdr->p_type, phdr->p_vaddr, phdr->p_offset, phdr->p_memsz); - startOffset = phdr->p_vaddr; - uint32_t* tt2 = (uint32_t*)prus[pru_num].instructionRam; - for (int x = 0; x < startOffset / 4; x++) { - // kind of a no-op (LDI r2, 1) to fill space until the real starting point - tt2[x] = 0x240001e2; - } - memcpy(&prus[pru_num].instructionRam[startOffset], &buf[phdr->p_offset], phdr->p_memsz); - __asm__ __volatile__("" :: - : "memory"); - } - } - } else { - printf("FIXME for 64bit\n"); - } - } else { - LogDebug(VB_CHANNELOUT, "Raw bin: %s\n", program.c_str()); - // raw bin file - if (file_size < prus[pru_num].instructionRamSize) { - memcpy(prus[pru_num].instructionRam, buf, file_size); - } - } - munmap(buf, file_size); + CopyFileContents(program, "/lib/firmware/" + FIRMWARE_PREFIX + "-pru" + std::to_string(pru_num) + "-fw"); + prus[pru_num].enable(); - /* - char bname[50]; - snprintf(bname, sizeof(bname), "/tmp/pru-%d.bin", pru_num); - fhand = open(bname, O_CREAT | O_RDWR); - write(fhand, prus[pru_num].instructionRam, 3000); - close(fhand); - */ + memset(prus[pru_num].dataRam, 0, prus[pru_num].dataRamSize); + memset(prus[pru_num].dataRam, 0, prus[pru_num].dataRamSize); - prus[pru_num].enable(startOffset); return false; } + void BBBPru::stop() { prus[pru_num].disable(); } diff --git a/src/util/BBBUtils.cpp b/src/util/BBBUtils.cpp index b9fde21c2..3460c96ad 100644 --- a/src/util/BBBUtils.cpp +++ b/src/util/BBBUtils.cpp @@ -211,6 +211,17 @@ int BBBPinCapabilities::configPin(const std::string& m, pinName[2] = '_'; } + if (FileExists("/usr/bin/pinctrl")) { + char buf[256]; + std::string pm = m; + if (m == "gpio" && directionOut) { + pm = "gpio_out"; + } + snprintf(buf, 256, "/usr/bin/pinctrl -s %s %s", pinName, m.c_str()); + printf("%s\n", buf); + system(buf); + } + snprintf(dir_name, sizeof(dir_name), "/sys/devices/platform/ocp/ocp:%s_pinmux/state", pinName); @@ -490,7 +501,7 @@ void BBBPinProvider::Init() { BBB_PINS.emplace_back("P2-05", 3, 24); BBB_PINS.emplace_back("P2-05b", 1, 5); BBB_PINS.emplace_back("P2-06", 2, 47); - BBB_PINS.emplace_back("P2-07", 3, 25); + BBB_PINS.emplace_back("P2-07", 3, 25).setUART("ttyS5-tx", 1); BBB_PINS.emplace_back("P2-07b", 1, 6); BBB_PINS.emplace_back("P2-08", 2, 48); BBB_PINS.emplace_back("P2-09", 3, 22);