LCOV - code coverage report
Current view: top level - AP_HAL - GPIO.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 3 47 6.4 %
Date: 2026-09-09 11:02:08 Functions: 1 5 20.0 %

          Line data    Source code
       1             : #include "GPIO.h"
       2             : 
       3             : #include <AP_HAL/AP_HAL.h>
       4             : 
       5             : #include <GCS_MAVLink/GCS.h>
       6             : 
       7             : extern const AP_HAL::HAL& hal;
       8             : 
       9        2290 : AP_HAL::PWMSource::~PWMSource()
      10             : {
      11        2290 :     if (interrupt_attached) {
      12             :         // Assume this is always successful
      13           0 :         hal.gpio->detach_interrupt(_pin);
      14           0 :         interrupt_attached = false;
      15             :     }
      16        2290 : }
      17             : 
      18           0 : bool AP_HAL::PWMSource::set_pin(int16_t new_pin, const char *subsystem)
      19             : {
      20           0 :     if (new_pin == _pin) {
      21             :         // we've already tried to attach to this pin
      22           0 :         return interrupt_attached;
      23             :     }
      24             : 
      25           0 :     if (interrupt_attached) {
      26           0 :         if (!hal.gpio->detach_interrupt(_pin)) {
      27           0 :             GCS_SEND_TEXT(MAV_SEVERITY_WARNING,
      28             :                           "%s: Failed to detach interrupt from %d",
      29             :                           subsystem,
      30             :                           _pin);
      31             :         }
      32           0 :         interrupt_attached = false;
      33             :     }
      34             : 
      35             :     // don't want to try to attach more than once:
      36           0 :     _pin = new_pin;
      37             : 
      38           0 :     if (_pin <= 0) {
      39             :         // invalid pin
      40           0 :         return false;
      41             :     }
      42             : 
      43             :     // install interrupt handler on rising and falling edge
      44           0 :     hal.gpio->pinMode(_pin, HAL_GPIO_INPUT);
      45           0 :     if (!hal.gpio->attach_interrupt(
      46           0 :             _pin,
      47             :             FUNCTOR_BIND_MEMBER(&AP_HAL::PWMSource::irq_handler,
      48             :                                 void,
      49             :                                 uint8_t,
      50             :                                 bool,
      51             :                                 uint32_t),
      52             :             AP_HAL::GPIO::INTERRUPT_BOTH)) {
      53             :         // failed to attach interrupt
      54           0 :         GCS_SEND_TEXT(MAV_SEVERITY_WARNING,
      55             :                       "%s: Failed to attach interrupt to %d",
      56             :                       subsystem,
      57             :                       _pin);
      58           0 :         return false;
      59             :     }
      60             : 
      61           0 :     interrupt_attached = true;
      62             : 
      63           0 :     return interrupt_attached;
      64             : }
      65             : 
      66             : // interrupt handler for reading pwm value
      67           0 : void AP_HAL::PWMSource::irq_handler(uint8_t a_pin, bool pin_high, uint32_t timestamp_us)
      68             : {
      69           0 :     if (pin_high) {
      70           0 :         _pulse_start_us = timestamp_us;
      71           0 :         return;
      72             :     }
      73           0 :     if (_pulse_start_us == 0) {
      74             :         // if we miss interrupts we could get two lows in a row.  If
      75             :         // we miss interrupts we're definitely handing back bad
      76             :         // values anyway....
      77           0 :         return;
      78             :     }
      79           0 :     _irq_value_us = timestamp_us - _pulse_start_us;
      80           0 :     _pulse_start_us = 0;
      81             : 
      82             :     // update fields for taking an average reading:
      83           0 :     _irq_value_us_sum += _irq_value_us;
      84           0 :     _irq_value_us_count++;
      85             : }
      86             : 
      87             : 
      88           0 : uint16_t AP_HAL::PWMSource::get_pwm_us()
      89             : {
      90             :     // disable interrupts and grab state
      91           0 :     void *irqstate = hal.scheduler->disable_interrupts_save();
      92           0 :     const uint32_t ret = _irq_value_us;
      93           0 :     _irq_value_us = 0;
      94           0 :     hal.scheduler->restore_interrupts(irqstate);
      95             : 
      96           0 :     return ret;
      97             : }
      98             : 
      99           0 : uint16_t AP_HAL::PWMSource::get_pwm_avg_us()
     100             : {
     101             :     // disable interrupts and grab state
     102           0 :     void *irqstate = hal.scheduler->disable_interrupts_save();
     103             :     uint32_t ret;
     104           0 :     if (_irq_value_us_count == 0) {
     105           0 :         ret = 0;
     106             :     } else {
     107           0 :         ret = _irq_value_us_sum / _irq_value_us_count;
     108             :     }
     109           0 :     _irq_value_us_sum = 0;
     110           0 :     _irq_value_us_count = 0;
     111           0 :     hal.scheduler->restore_interrupts(irqstate);
     112             : 
     113           0 :     return ret;
     114             : }

Generated by: LCOV version 1.14