| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title GpioDriver.cpp | ||
| 3 | // \author tumbar | ||
| 4 | // \brief cpp file for GpioDriver component implementation class | ||
| 5 | // ====================================================================== | ||
| 6 | |||
| 7 | #include "fprime-samd/Drv/GpioDriver/GpioDriver.hpp" | ||
| 8 | #include "fprime-samd/Drv/GpioDriver/GpioDriverHardware.hpp" | ||
| 9 | |||
| 10 | namespace Samd21 { | ||
| 11 | |||
| 12 | // ---------------------------------------------------------------------- | ||
| 13 | // Component construction and destruction | ||
| 14 | // ---------------------------------------------------------------------- | ||
| 15 | |||
| 16 | ✗ | GpioDriver ::GpioDriver(const char* const compName) | |
| 17 | : GpioDriverComponentBase(compName), | ||
| 18 | ✗ | m_configured(false), | |
| 19 | ✗ | m_mode(Mode::INPUT), | |
| 20 | ✗ | m_group(Group::PA), | |
| 21 | ✗ | m_pin(Pin::PIN_0) {} | |
| 22 | |||
| 23 | ✗ | GpioDriver ::~GpioDriver() {} | |
| 24 | |||
| 25 | ✗ | void GpioDriver ::configureInput(Group group, | |
| 26 | Pin pin, | ||
| 27 | InputPullMode input_pull_mode, | ||
| 28 | ExternalInterruptMode interrupt_mode) { | ||
| 29 | ✗ | FW_ASSERT(!this->m_configured); | |
| 30 | |||
| 31 | ✗ | this->m_group = group; | |
| 32 | ✗ | this->m_pin = pin; | |
| 33 | ✗ | this->m_mode = Mode::INPUT; | |
| 34 | |||
| 35 | ✗ | const U8 groupIdx = static_cast<U8>(group); | |
| 36 | ✗ | const U8 pinIdx = static_cast<U8>(pin); | |
| 37 | ✗ | GpioHardware::GpioHal::configureInput(groupIdx, pinIdx, input_pull_mode); | |
| 38 | |||
| 39 | // Register for ISR dispatch before enabling the interrupt, so EIC_Handler | ||
| 40 | // never sees the interrupt live with no handler registered for this line. | ||
| 41 | ✗ | if (interrupt_mode != ExternalInterruptMode::NONE) { | |
| 42 | ✗ | GpioHardware::registerInterruptHandler(pinIdx, this); | |
| 43 | ✗ | GpioHardware::GpioHal::configureExternalInterrupt(groupIdx, pinIdx, interrupt_mode); | |
| 44 | } | ||
| 45 | |||
| 46 | ✗ | this->m_configured = true; | |
| 47 | ✗ | } | |
| 48 | |||
| 49 | ✗ | void GpioDriver ::configureOutput(Group group, Pin pin) { | |
| 50 | ✗ | FW_ASSERT(!this->m_configured); | |
| 51 | |||
| 52 | ✗ | this->m_group = group; | |
| 53 | ✗ | this->m_pin = pin; | |
| 54 | ✗ | this->m_mode = Mode::OUTPUT; | |
| 55 | |||
| 56 | ✗ | const U8 groupIdx = static_cast<U8>(group); | |
| 57 | ✗ | const U8 pinIdx = static_cast<U8>(pin); | |
| 58 | ✗ | GpioHardware::GpioHal::configureOutput(groupIdx, pinIdx); | |
| 59 | |||
| 60 | ✗ | this->m_configured = true; | |
| 61 | ✗ | } | |
| 62 | |||
| 63 | ✗ | void GpioDriver ::gpioInterruptIsr() { | |
| 64 | // Nothing to emit if the interrupt notification port is not wired up. | ||
| 65 | ✗ | if (!this->isConnected_gpioInterrupt_OutputPort(0)) { | |
| 66 | ✗ | return; | |
| 67 | } | ||
| 68 | |||
| 69 | // Timestamp the edge and emit it as a cycle to the connected consumer. | ||
| 70 | ✗ | Os::RawTime cycleStart; | |
| 71 | ✗ | (void)cycleStart.now(); | |
| 72 | ✗ | this->gpioInterrupt_out(0, cycleStart); | |
| 73 | ✗ | } | |
| 74 | |||
| 75 | // ---------------------------------------------------------------------- | ||
| 76 | // Handler implementations for typed input ports | ||
| 77 | // ---------------------------------------------------------------------- | ||
| 78 | |||
| 79 | ✗ | Drv::GpioStatus GpioDriver ::gpioRead_handler(FwIndexType portNum, Fw::Logic& state) { | |
| 80 | ✗ | if (!this->m_configured) { | |
| 81 | ✗ | return Drv::GpioStatus::NOT_OPENED; | |
| 82 | } | ||
| 83 | |||
| 84 | ✗ | if (this->m_mode != Mode::INPUT) { | |
| 85 | ✗ | return Drv::GpioStatus::INVALID_MODE; | |
| 86 | } | ||
| 87 | |||
| 88 | ✗ | state = GpioHardware::GpioHal::read(static_cast<U8>(this->m_group), static_cast<U8>(this->m_pin)); | |
| 89 | ✗ | return Drv::GpioStatus::OP_OK; | |
| 90 | } | ||
| 91 | |||
| 92 | ✗ | Drv::GpioStatus GpioDriver ::gpioWrite_handler(FwIndexType portNum, const Fw::Logic& state) { | |
| 93 | ✗ | if (!this->m_configured) { | |
| 94 | ✗ | return Drv::GpioStatus::NOT_OPENED; | |
| 95 | } | ||
| 96 | |||
| 97 | ✗ | if (this->m_mode != Mode::OUTPUT) { | |
| 98 | ✗ | return Drv::GpioStatus::INVALID_MODE; | |
| 99 | } | ||
| 100 | |||
| 101 | ✗ | GpioHardware::GpioHal::write(static_cast<U8>(this->m_group), static_cast<U8>(this->m_pin), state); | |
| 102 | ✗ | return Drv::GpioStatus::OP_OK; | |
| 103 | } | ||
| 104 | |||
| 105 | } // namespace Samd21 | ||
| 106 |