1b797b3e1SBen Tyner #include <attn/attn_handler.hpp> 2b797b3e1SBen Tyner #include <attn/attn_monitor.hpp> 3*bfa831a8Saustinfcui #include <util/trace.hpp> 473ac368aSBen Tyner 573ac368aSBen Tyner namespace attn 673ac368aSBen Tyner { 773ac368aSBen Tyner 873ac368aSBen Tyner /** @brief Register a callback for gpio event */ scheduleGPIOEvent()973ac368aSBen Tynervoid AttnMonitor::scheduleGPIOEvent() 1073ac368aSBen Tyner { 1173ac368aSBen Tyner // Register async callback, note that callback is a 1273ac368aSBen Tyner // lambda function with "this" pointer captured 1373ac368aSBen Tyner iv_gpioEventDescriptor.async_wait( 1473ac368aSBen Tyner boost::asio::posix::stream_descriptor::wait_read, 1573ac368aSBen Tyner [this](const boost::system::error_code& ec) { 1673ac368aSBen Tyner if (ec) 1773ac368aSBen Tyner { 18*bfa831a8Saustinfcui trace::err("GPIO Async wait error: %s", ec.message().c_str()); 1973ac368aSBen Tyner } 2073ac368aSBen Tyner else 2173ac368aSBen Tyner { 22*bfa831a8Saustinfcui trace::inf("Attention GPIO active"); 2373ac368aSBen Tyner handleGPIOEvent(); // gpio trigger detected 2473ac368aSBen Tyner } 2573ac368aSBen Tyner return; 2673ac368aSBen Tyner }); // register async callback 2773ac368aSBen Tyner } 2873ac368aSBen Tyner 2973ac368aSBen Tyner /** @brief Handle the GPIO state change event */ handleGPIOEvent()3073ac368aSBen Tynervoid AttnMonitor::handleGPIOEvent() 3173ac368aSBen Tyner { 3273ac368aSBen Tyner gpiod_line_event gpioEvent; 3373ac368aSBen Tyner 3473ac368aSBen Tyner if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(), 3573ac368aSBen Tyner &gpioEvent) < 0) 3673ac368aSBen Tyner { 37*bfa831a8Saustinfcui trace::err("GPIO line read failed"); 3873ac368aSBen Tyner } 3973ac368aSBen Tyner else 4073ac368aSBen Tyner { 4173ac368aSBen Tyner switch (gpiod_line_get_value(iv_gpioLine)) 4273ac368aSBen Tyner { 4373ac368aSBen Tyner // active attention when gpio == 0 4473ac368aSBen Tyner case 0: 453fb52e53SBen Tyner attnHandler(iv_config); 4673ac368aSBen Tyner break; 4773ac368aSBen Tyner 4873ac368aSBen Tyner // gpio == 1, GPIO handler should not be executing 4973ac368aSBen Tyner case 1: 50*bfa831a8Saustinfcui trace::inf("GPIO handler out of sync"); 5173ac368aSBen Tyner break; 5273ac368aSBen Tyner 5373ac368aSBen Tyner // unexpected value 5473ac368aSBen Tyner default: 55*bfa831a8Saustinfcui trace::inf("GPIO line unexpected value"); 5673ac368aSBen Tyner } 5773ac368aSBen Tyner } 5873ac368aSBen Tyner scheduleGPIOEvent(); // continue monitoring gpio 5973ac368aSBen Tyner } 6073ac368aSBen Tyner 6173ac368aSBen Tyner /** @brief Request a GPIO line for monitoring attention events */ requestGPIOEvent()6273ac368aSBen Tynervoid AttnMonitor::requestGPIOEvent() 6373ac368aSBen Tyner { 6473ac368aSBen Tyner if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0)) 6573ac368aSBen Tyner { 66*bfa831a8Saustinfcui trace::err("failed request for GPIO"); 6773ac368aSBen Tyner } 6873ac368aSBen Tyner else 6973ac368aSBen Tyner { 7073ac368aSBen Tyner int gpioLineFd; 7173ac368aSBen Tyner 7273ac368aSBen Tyner gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine); 7373ac368aSBen Tyner if (gpioLineFd < 0) 7473ac368aSBen Tyner { 75*bfa831a8Saustinfcui trace::err("failed to get file descriptor"); 7673ac368aSBen Tyner } 7773ac368aSBen Tyner else 7873ac368aSBen Tyner { 7973ac368aSBen Tyner // Register file descriptor for monitoring 8073ac368aSBen Tyner iv_gpioEventDescriptor.assign(gpioLineFd); 8173ac368aSBen Tyner 8273ac368aSBen Tyner // Start monitoring 8373ac368aSBen Tyner scheduleGPIOEvent(); 8473ac368aSBen Tyner } 8573ac368aSBen Tyner } 8673ac368aSBen Tyner } 8773ac368aSBen Tyner 8873ac368aSBen Tyner } // namespace attn 89