| 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 | 83 | GpioDriver ::GpioDriver(const char* const compName) | |
| 17 | : GpioDriverComponentBase(compName), | ||
| 18 | 83 | m_configured(false), | |
| 19 | 83 | m_mode(Mode::INPUT), | |
| 20 | 83 | m_group(Group::PA), | |
| 21 | 166 | m_pin(Pin::PIN_0) {} | |
| 22 | |||
| 23 | 166 | GpioDriver ::~GpioDriver() {} | |
| 24 | |||
| 25 | 11 | void GpioDriver ::configureInput(Group group, | |
| 26 | Pin pin, | ||
| 27 | Gpio::InputPullMode input_pull_mode, | ||
| 28 | ExternalInterruptMode interrupt_mode) { | ||
| 29 | 11 | FW_ASSERT(!this->m_configured); | |
| 30 | |||
| 31 | 11 | this->m_group = group; | |
| 32 | 11 | this->m_pin = pin; | |
| 33 | 11 | this->m_mode = Mode::INPUT; | |
| 34 | |||
| 35 | 11 | const U8 groupIdx = static_cast<U8>(group); | |
| 36 | 11 | const U8 pinIdx = static_cast<U8>(pin); | |
| 37 | 11 | 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 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
|
11 | if (interrupt_mode != ExternalInterruptMode::NONE) { |
| 42 | 5 | GpioHardware::registerInterruptHandler(pinIdx, this); | |
| 43 | 5 | GpioHardware::GpioHal::configureExternalInterrupt(groupIdx, pinIdx, interrupt_mode); | |
| 44 | } | ||
| 45 | |||
| 46 | 11 | this->m_configured = true; | |
| 47 | 11 | } | |
| 48 | |||
| 49 | 67 | void GpioDriver ::configureOutput(Group group, Pin pin, Fw::Logic initial_state) { | |
| 50 | 67 | FW_ASSERT(!this->m_configured); | |
| 51 | |||
| 52 | 67 | this->m_group = group; | |
| 53 | 67 | this->m_pin = pin; | |
| 54 | 67 | this->m_mode = Mode::OUTPUT; | |
| 55 | |||
| 56 | 67 | const U8 groupIdx = static_cast<U8>(group); | |
| 57 | 67 | const U8 pinIdx = static_cast<U8>(pin); | |
| 58 |
2/2✓ Branch 2 taken 67 times.
✓ Branch 5 taken 67 times.
|
67 | GpioHardware::GpioHal::configureOutput(groupIdx, pinIdx, initial_state); |
| 59 | |||
| 60 | 67 | this->m_configured = true; | |
| 61 | 67 | } | |
| 62 | |||
| 63 | 3 | void GpioDriver ::gpioInterruptIsr() { | |
| 64 | // Nothing to emit if the interrupt notification port is not wired up. | ||
| 65 |
3/3✓ Branch 5 taken 3 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 2 times.
|
3 | if (!this->isConnected_gpioInterrupt_OutputPort(0)) { |
| 66 | 1 | return; | |
| 67 | } | ||
| 68 | |||
| 69 | // Timestamp the edge and emit it as a cycle to the connected consumer. | ||
| 70 |
1/1✓ Branch 2 taken 2 times.
|
2 | Os::RawTime cycleStart; |
| 71 |
1/1✓ Branch 2 taken 2 times.
|
2 | (void)cycleStart.now(); |
| 72 |
1/1✓ Branch 5 taken 2 times.
|
2 | this->gpioInterrupt_out(0, cycleStart); |
| 73 | 2 | } | |
| 74 | |||
| 75 | // ---------------------------------------------------------------------- | ||
| 76 | // Handler implementations for typed input ports | ||
| 77 | // ---------------------------------------------------------------------- | ||
| 78 | |||
| 79 | 4 | Drv::GpioStatus GpioDriver ::gpioRead_handler(FwIndexType portNum, Fw::Logic& state) { | |
| 80 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
|
4 | if (!this->m_configured) { |
| 81 | 1 | return Drv::GpioStatus::NOT_OPENED; | |
| 82 | } | ||
| 83 | |||
| 84 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
|
3 | if (this->m_mode != Mode::INPUT) { |
| 85 | 1 | return Drv::GpioStatus::INVALID_MODE; | |
| 86 | } | ||
| 87 | |||
| 88 |
2/2✓ Branch 10 taken 2 times.
✓ Branch 17 taken 2 times.
|
2 | state = GpioHardware::GpioHal::read(static_cast<U8>(this->m_group), static_cast<U8>(this->m_pin)); |
| 89 | 2 | return Drv::GpioStatus::OP_OK; | |
| 90 | } | ||
| 91 | |||
| 92 | 4 | Drv::GpioStatus GpioDriver ::gpioWrite_handler(FwIndexType portNum, const Fw::Logic& state) { | |
| 93 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
|
4 | if (!this->m_configured) { |
| 94 | 1 | return Drv::GpioStatus::NOT_OPENED; | |
| 95 | } | ||
| 96 | |||
| 97 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
|
3 | if (this->m_mode != Mode::OUTPUT) { |
| 98 | 1 | return Drv::GpioStatus::INVALID_MODE; | |
| 99 | } | ||
| 100 | |||
| 101 | 2 | GpioHardware::GpioHal::write(static_cast<U8>(this->m_group), static_cast<U8>(this->m_pin), state); | |
| 102 | 2 | return Drv::GpioStatus::OP_OK; | |
| 103 | } | ||
| 104 | |||
| 105 | } // namespace Samd21 | ||
| 106 |