123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #include "Device.h"
- #include <AP_HAL/AP_HAL.h>
- #include <AP_HAL/utility/OwnPtr.h>
- #include <stdio.h>
- #if HAL_USE_I2C == TRUE || HAL_USE_SPI == TRUE
- #include "Scheduler.h"
- #include "Semaphores.h"
- #include "Util.h"
- #include "hwdef/common/stm32_util.h"
- #ifndef HAL_DEVICE_THREAD_STACK
- #define HAL_DEVICE_THREAD_STACK 1024
- #endif
- using namespace ChibiOS;
- static const AP_HAL::HAL &hal = AP_HAL::get_HAL();
- DeviceBus::DeviceBus(uint8_t _thread_priority) :
- thread_priority(_thread_priority)
- {
- bouncebuffer_init(&bounce_buffer_tx, 10, false);
- bouncebuffer_init(&bounce_buffer_rx, 10, false);
- }
- void DeviceBus::bus_thread(void *arg)
- {
- struct DeviceBus *binfo = (struct DeviceBus *)arg;
- while (true) {
- uint64_t now = AP_HAL::micros64();
- DeviceBus::callback_info *callback;
-
- for (callback = binfo->callbacks; callback; callback = callback->next) {
- if (now >= callback->next_usec) {
- while (now >= callback->next_usec) {
- callback->next_usec += callback->period_usec;
- }
-
- if (binfo->semaphore.take(HAL_SEMAPHORE_BLOCK_FOREVER)) {
- callback->cb();
- binfo->semaphore.give();
- }
- }
- }
-
- uint64_t next_needed = 0;
- now = AP_HAL::micros64();
- for (callback = binfo->callbacks; callback; callback = callback->next) {
- if (next_needed == 0 ||
- callback->next_usec < next_needed) {
- next_needed = callback->next_usec;
- if (next_needed < now) {
- next_needed = now;
- }
- }
- }
-
- uint32_t delay = 50000;
- if (next_needed >= now && next_needed - now < delay) {
- delay = next_needed - now;
- }
-
-
- if (delay < 100) {
- delay = 100;
- }
- hal.scheduler->delay_microseconds(delay);
- }
- return;
- }
- #if CH_CFG_USE_HEAP == TRUE
- AP_HAL::Device::PeriodicHandle DeviceBus::register_periodic_callback(uint32_t period_usec, AP_HAL::Device::PeriodicCb cb, AP_HAL::Device *_hal_device)
- {
- if (!thread_started) {
- thread_started = true;
- hal_device = _hal_device;
-
- const uint8_t name_len = 7;
- char *name = (char *)malloc(name_len);
- switch (hal_device->bus_type()) {
- case AP_HAL::Device::BUS_TYPE_I2C:
- snprintf(name, name_len, "I2C:%u",
- hal_device->bus_num());
- break;
- case AP_HAL::Device::BUS_TYPE_SPI:
- snprintf(name, name_len, "SPI:%u",
- hal_device->bus_num());
- break;
- default:
- break;
- }
- thread_ctx = thread_create_alloc(THD_WORKING_AREA_SIZE(HAL_DEVICE_THREAD_STACK),
- name,
- thread_priority,
- DeviceBus::bus_thread,
- this);
- if (thread_ctx == nullptr) {
- AP_HAL::panic("Failed to create bus thread %s", name);
- }
- }
- DeviceBus::callback_info *callback = new DeviceBus::callback_info;
- if (callback == nullptr) {
- return nullptr;
- }
- callback->cb = cb;
- callback->period_usec = period_usec;
- callback->next_usec = AP_HAL::micros64() + period_usec;
-
- callback->next = callbacks;
- callbacks = callback;
- return callback;
- }
- #endif
- bool DeviceBus::adjust_timer(AP_HAL::Device::PeriodicHandle h, uint32_t period_usec)
- {
- if (chThdGetSelfX() != thread_ctx) {
- return false;
- }
- DeviceBus::callback_info *callback = static_cast<DeviceBus::callback_info *>(h);
- callback->period_usec = period_usec;
- callback->next_usec = AP_HAL::micros64() + period_usec;
- return true;
- }
- void DeviceBus::bouncebuffer_setup(const uint8_t *&buf_tx, uint16_t tx_len,
- uint8_t *&buf_rx, uint16_t rx_len)
- {
- if (buf_rx) {
- bouncebuffer_setup_read(bounce_buffer_rx, &buf_rx, rx_len);
- }
- if (buf_tx) {
- bouncebuffer_setup_write(bounce_buffer_tx, &buf_tx, tx_len);
- }
- }
- void DeviceBus::bouncebuffer_finish(const uint8_t *buf_tx, uint8_t *buf_rx, uint16_t rx_len)
- {
- if (buf_rx) {
- bouncebuffer_finish_read(bounce_buffer_rx, buf_rx, rx_len);
- }
- if (buf_tx) {
- bouncebuffer_finish_write(bounce_buffer_tx, buf_tx);
- }
- }
- #endif
|