mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
AP_HAL_Linux: Implement threaded SPI
This commit is contained in:
parent
ea0595c7ac
commit
8541d5339d
@ -32,6 +32,10 @@
|
|||||||
#include <AP_HAL/utility/OwnPtr.h>
|
#include <AP_HAL/utility/OwnPtr.h>
|
||||||
|
|
||||||
#include "GPIO.h"
|
#include "GPIO.h"
|
||||||
|
#include "PollerThread.h"
|
||||||
|
#include "Scheduler.h"
|
||||||
|
#include "Semaphores.h"
|
||||||
|
#include "Thread.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
namespace Linux {
|
namespace Linux {
|
||||||
@ -134,12 +138,20 @@ const uint8_t SPIDeviceManager::_n_device_desc = LINUX_SPI_DEVICE_NUM_DEVICES;
|
|||||||
|
|
||||||
|
|
||||||
/* Private struct to maintain for each bus */
|
/* Private struct to maintain for each bus */
|
||||||
class SPIBus {
|
class SPIBus : public TimerPollable::WrapperCb {
|
||||||
public:
|
public:
|
||||||
~SPIBus();
|
~SPIBus();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TimerPollable::WrapperCb methods to take
|
||||||
|
* and release semaphore while calling the callback
|
||||||
|
*/
|
||||||
|
void start_cb() override;
|
||||||
|
void end_cb() override;
|
||||||
|
|
||||||
int open(uint16_t bus_, uint16_t kernel_cs_);
|
int open(uint16_t bus_, uint16_t kernel_cs_);
|
||||||
|
|
||||||
|
PollerThread thread;
|
||||||
Semaphore sem;
|
Semaphore sem;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
uint16_t bus;
|
uint16_t bus;
|
||||||
@ -154,6 +166,16 @@ SPIBus::~SPIBus()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPIBus::start_cb()
|
||||||
|
{
|
||||||
|
sem.take(HAL_SEMAPHORE_BLOCK_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPIBus::end_cb()
|
||||||
|
{
|
||||||
|
sem.give();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SPIBus::open(uint16_t bus_, uint16_t kernel_cs_)
|
int SPIBus::open(uint16_t bus_, uint16_t kernel_cs_)
|
||||||
{
|
{
|
||||||
@ -336,6 +358,33 @@ int SPIDevice::get_fd()
|
|||||||
return _bus.fd;
|
return _bus.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AP_HAL::Device::PeriodicHandle SPIDevice::register_periodic_callback(
|
||||||
|
uint32_t period_usec, AP_HAL::Device::PeriodicCb cb)
|
||||||
|
{
|
||||||
|
TimerPollable *p = _bus.thread.add_timer(cb, &_bus, period_usec);
|
||||||
|
if (!p) {
|
||||||
|
AP_HAL::panic("Could not create periodic callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_bus.thread.is_started()) {
|
||||||
|
char name[16];
|
||||||
|
snprintf(name, sizeof(name), "ap-spi-%u", _bus.bus);
|
||||||
|
|
||||||
|
_bus.thread.set_stack_size(AP_LINUX_SENSORS_STACK_SIZE);
|
||||||
|
_bus.thread.start(name, AP_LINUX_SENSORS_SCHED_POLICY,
|
||||||
|
AP_LINUX_SENSORS_SCHED_PRIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<AP_HAL::Device::PeriodicHandle>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SPIDevice::adjust_periodic_callback(
|
||||||
|
AP_HAL::Device::PeriodicHandle h, uint32_t period_usec)
|
||||||
|
{
|
||||||
|
return _bus.thread.adjust_timer(static_cast<TimerPollable*>(h), period_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AP_HAL::OwnPtr<AP_HAL::SPIDevice>
|
AP_HAL::OwnPtr<AP_HAL::SPIDevice>
|
||||||
SPIDeviceManager::get_device(const char *name)
|
SPIDeviceManager::get_device(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -52,10 +52,11 @@ public:
|
|||||||
|
|
||||||
/* See AP_HAL::Device::register_periodic_callback() */
|
/* See AP_HAL::Device::register_periodic_callback() */
|
||||||
AP_HAL::Device::PeriodicHandle register_periodic_callback(
|
AP_HAL::Device::PeriodicHandle register_periodic_callback(
|
||||||
uint32_t period_usec, AP_HAL::Device::PeriodicCb) override
|
uint32_t period_usec, AP_HAL::Device::PeriodicCb) override;
|
||||||
{
|
|
||||||
return nullptr;
|
/* See AP_HAL::Device::adjust_periodic_callback() */
|
||||||
}
|
bool adjust_periodic_callback(
|
||||||
|
AP_HAL::Device::PeriodicHandle h, uint32_t period_usec) override;
|
||||||
|
|
||||||
/* See AP_HAL::Device::get_fd() */
|
/* See AP_HAL::Device::get_fd() */
|
||||||
int get_fd() override;
|
int get_fd() override;
|
||||||
|
Loading…
Reference in New Issue
Block a user