2018-01-05 02:19:51 -04:00
|
|
|
/*
|
|
|
|
* This file is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Code by Andrew Tridgell and Siddharth Bharat Purohit
|
|
|
|
*/
|
|
|
|
#include <AP_HAL/AP_HAL.h>
|
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "HAL_ChibiOS_Class.h"
|
|
|
|
#include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
|
|
|
|
#include <AP_HAL_ChibiOS/AP_HAL_ChibiOS_Private.h>
|
|
|
|
#include "shared_dma.h"
|
2018-04-28 21:09:09 -03:00
|
|
|
#include "sdcard.h"
|
2018-03-06 18:41:03 -04:00
|
|
|
#include "hwdef/common/usbcfg.h"
|
2018-07-11 02:11:36 -03:00
|
|
|
#include "hwdef/common/stm32_util.h"
|
2019-04-11 05:01:49 -03:00
|
|
|
#include "hwdef/common/watchdog.h"
|
2019-04-11 05:25:51 -03:00
|
|
|
#include <AP_BoardConfig/AP_BoardConfig.h>
|
2019-04-19 23:58:48 -03:00
|
|
|
#include <AP_InternalError/AP_InternalError.h>
|
2019-05-09 16:58:36 -03:00
|
|
|
#ifndef HAL_BOOTLOADER_BUILD
|
2019-05-09 08:15:58 -03:00
|
|
|
#include <AP_Logger/AP_Logger.h>
|
2019-05-09 16:58:36 -03:00
|
|
|
#endif
|
2018-01-05 02:19:51 -04:00
|
|
|
|
2018-01-11 21:41:45 -04:00
|
|
|
#include <hwdef.h>
|
|
|
|
|
2018-06-25 00:38:58 -03:00
|
|
|
#ifndef HAL_NO_UARTDRIVER
|
2018-01-11 21:41:45 -04:00
|
|
|
static HAL_UARTA_DRIVER;
|
|
|
|
static HAL_UARTB_DRIVER;
|
|
|
|
static HAL_UARTC_DRIVER;
|
|
|
|
static HAL_UARTD_DRIVER;
|
|
|
|
static HAL_UARTE_DRIVER;
|
|
|
|
static HAL_UARTF_DRIVER;
|
2018-06-27 08:34:23 -03:00
|
|
|
static HAL_UARTG_DRIVER;
|
2018-06-25 00:38:58 -03:00
|
|
|
#else
|
|
|
|
static Empty::UARTDriver uartADriver;
|
|
|
|
static Empty::UARTDriver uartBDriver;
|
|
|
|
static Empty::UARTDriver uartCDriver;
|
|
|
|
static Empty::UARTDriver uartDDriver;
|
|
|
|
static Empty::UARTDriver uartEDriver;
|
|
|
|
static Empty::UARTDriver uartFDriver;
|
2018-06-27 08:34:23 -03:00
|
|
|
static Empty::UARTDriver uartGDriver;
|
2018-06-25 00:38:58 -03:00
|
|
|
#endif
|
2018-03-01 20:46:30 -04:00
|
|
|
|
|
|
|
#if HAL_USE_I2C == TRUE
|
2018-01-05 02:19:51 -04:00
|
|
|
static ChibiOS::I2CDeviceManager i2cDeviceManager;
|
2018-03-01 20:46:30 -04:00
|
|
|
#else
|
|
|
|
static Empty::I2CDeviceManager i2cDeviceManager;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if HAL_USE_SPI == TRUE
|
2018-01-05 02:19:51 -04:00
|
|
|
static ChibiOS::SPIDeviceManager spiDeviceManager;
|
2018-03-01 20:46:30 -04:00
|
|
|
#else
|
|
|
|
static Empty::SPIDeviceManager spiDeviceManager;
|
|
|
|
#endif
|
|
|
|
|
2018-10-28 20:24:01 -03:00
|
|
|
#if HAL_USE_ADC == TRUE && !defined(HAL_DISABLE_ADC_DRIVER)
|
2018-01-13 00:02:05 -04:00
|
|
|
static ChibiOS::AnalogIn analogIn;
|
2018-03-06 18:41:03 -04:00
|
|
|
#else
|
|
|
|
static Empty::AnalogIn analogIn;
|
|
|
|
#endif
|
|
|
|
|
2018-01-26 22:35:53 -04:00
|
|
|
#ifdef HAL_USE_EMPTY_STORAGE
|
|
|
|
static Empty::Storage storageDriver;
|
|
|
|
#else
|
2018-01-13 00:02:05 -04:00
|
|
|
static ChibiOS::Storage storageDriver;
|
2018-01-26 22:35:53 -04:00
|
|
|
#endif
|
2018-01-13 00:02:05 -04:00
|
|
|
static ChibiOS::GPIO gpioDriver;
|
|
|
|
static ChibiOS::RCInput rcinDriver;
|
2018-03-01 20:46:30 -04:00
|
|
|
|
|
|
|
#if HAL_USE_PWM == TRUE
|
2018-01-13 00:02:05 -04:00
|
|
|
static ChibiOS::RCOutput rcoutDriver;
|
2018-03-01 20:46:30 -04:00
|
|
|
#else
|
|
|
|
static Empty::RCOutput rcoutDriver;
|
|
|
|
#endif
|
|
|
|
|
2018-01-13 00:02:05 -04:00
|
|
|
static ChibiOS::Scheduler schedulerInstance;
|
|
|
|
static ChibiOS::Util utilInstance;
|
2018-01-05 02:19:51 -04:00
|
|
|
static Empty::OpticalFlow opticalFlowDriver;
|
2019-04-08 01:22:26 -03:00
|
|
|
|
|
|
|
#ifndef HAL_NO_FLASH_SUPPORT
|
2019-03-25 21:13:51 -03:00
|
|
|
static ChibiOS::Flash flashDriver;
|
2019-04-08 01:22:26 -03:00
|
|
|
#else
|
|
|
|
static Empty::Flash flashDriver;
|
|
|
|
#endif
|
2018-04-28 21:09:09 -03:00
|
|
|
|
2018-01-05 02:19:51 -04:00
|
|
|
|
|
|
|
#if HAL_WITH_IO_MCU
|
2018-01-11 21:41:45 -04:00
|
|
|
HAL_UART_IO_DRIVER;
|
2018-01-05 02:19:51 -04:00
|
|
|
#include <AP_IOMCU/AP_IOMCU.h>
|
|
|
|
AP_IOMCU iomcu(uart_io);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
HAL_ChibiOS::HAL_ChibiOS() :
|
|
|
|
AP_HAL::HAL(
|
|
|
|
&uartADriver,
|
|
|
|
&uartBDriver,
|
|
|
|
&uartCDriver,
|
|
|
|
&uartDDriver,
|
|
|
|
&uartEDriver,
|
2018-01-11 21:41:45 -04:00
|
|
|
&uartFDriver,
|
2018-06-27 08:34:23 -03:00
|
|
|
&uartGDriver,
|
2018-01-05 02:19:51 -04:00
|
|
|
&i2cDeviceManager,
|
|
|
|
&spiDeviceManager,
|
|
|
|
&analogIn,
|
|
|
|
&storageDriver,
|
|
|
|
&uartADriver,
|
|
|
|
&gpioDriver,
|
|
|
|
&rcinDriver,
|
|
|
|
&rcoutDriver,
|
|
|
|
&schedulerInstance,
|
|
|
|
&utilInstance,
|
|
|
|
&opticalFlowDriver,
|
2019-03-25 21:13:51 -03:00
|
|
|
&flashDriver,
|
2018-01-05 02:19:51 -04:00
|
|
|
nullptr
|
|
|
|
)
|
|
|
|
{}
|
|
|
|
|
|
|
|
static bool thread_running = false; /**< Daemon status flag */
|
|
|
|
static thread_t* daemon_task; /**< Handle of daemon task / thread */
|
|
|
|
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
set the priority of the main APM task
|
|
|
|
*/
|
|
|
|
void hal_chibios_set_priority(uint8_t priority)
|
|
|
|
{
|
|
|
|
chSysLock();
|
2018-03-06 18:41:03 -04:00
|
|
|
#if CH_CFG_USE_MUTEXES == TRUE
|
2018-01-05 02:19:51 -04:00
|
|
|
if ((daemon_task->prio == daemon_task->realprio) || (priority > daemon_task->prio)) {
|
|
|
|
daemon_task->prio = priority;
|
|
|
|
}
|
|
|
|
daemon_task->realprio = priority;
|
2018-03-06 18:41:03 -04:00
|
|
|
#endif
|
2018-01-05 02:19:51 -04:00
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
thread_t* get_main_thread()
|
|
|
|
{
|
|
|
|
return daemon_task;
|
|
|
|
}
|
|
|
|
|
|
|
|
static AP_HAL::HAL::Callbacks* g_callbacks;
|
2018-08-29 10:11:48 -03:00
|
|
|
|
|
|
|
static void main_loop()
|
2018-01-05 02:19:51 -04:00
|
|
|
{
|
|
|
|
daemon_task = chThdGetSelfX();
|
|
|
|
|
2018-08-29 10:11:48 -03:00
|
|
|
/*
|
|
|
|
switch to high priority for main loop
|
|
|
|
*/
|
|
|
|
chThdSetPriority(APM_MAIN_PRIORITY);
|
|
|
|
|
2018-02-06 19:48:36 -04:00
|
|
|
#ifdef HAL_I2C_CLEAR_BUS
|
|
|
|
// Clear all I2C Buses. This can be needed on some boards which
|
|
|
|
// can get a stuck I2C peripheral on boot
|
2018-02-05 15:40:05 -04:00
|
|
|
ChibiOS::I2CBus::clear_all();
|
2018-02-06 19:48:36 -04:00
|
|
|
#endif
|
2018-02-05 15:40:05 -04:00
|
|
|
|
2018-08-29 10:14:12 -03:00
|
|
|
#if STM32_DMA_ADVANCED
|
2018-01-13 00:02:05 -04:00
|
|
|
ChibiOS::Shared_DMA::init();
|
2018-08-29 10:14:12 -03:00
|
|
|
#endif
|
2018-07-12 07:47:48 -03:00
|
|
|
peripheral_power_enable();
|
|
|
|
|
2018-01-05 02:19:51 -04:00
|
|
|
hal.uartA->begin(115200);
|
2018-03-07 17:42:35 -04:00
|
|
|
|
|
|
|
#ifdef HAL_SPI_CHECK_CLOCK_FREQ
|
|
|
|
// optional test of SPI clock frequencies
|
|
|
|
ChibiOS::SPIDevice::test_clock_freq();
|
2018-04-28 21:09:09 -03:00
|
|
|
#endif
|
|
|
|
|
2018-01-05 02:19:51 -04:00
|
|
|
hal.uartB->begin(38400);
|
|
|
|
hal.uartC->begin(57600);
|
|
|
|
hal.analogin->init();
|
|
|
|
hal.scheduler->init();
|
|
|
|
|
|
|
|
/*
|
|
|
|
run setup() at low priority to ensure CLI doesn't hang the
|
|
|
|
system, and to allow initial sensor read loops to run
|
|
|
|
*/
|
|
|
|
hal_chibios_set_priority(APM_STARTUP_PRIORITY);
|
|
|
|
|
2019-05-09 04:49:32 -03:00
|
|
|
if (stm32_was_watchdog_reset()) {
|
|
|
|
// load saved watchdog data
|
|
|
|
stm32_watchdog_load((uint32_t *)&utilInstance.persistent_data, (sizeof(utilInstance.persistent_data)+3)/4);
|
|
|
|
}
|
|
|
|
|
2019-05-09 08:15:58 -03:00
|
|
|
schedulerInstance.hal_initialized();
|
2018-01-05 02:19:51 -04:00
|
|
|
|
2019-05-09 08:15:58 -03:00
|
|
|
g_callbacks->setup();
|
2018-01-05 02:19:51 -04:00
|
|
|
|
2019-05-09 16:58:36 -03:00
|
|
|
#ifdef IOMCU_FW
|
|
|
|
stm32_watchdog_init();
|
|
|
|
#elif !defined(HAL_BOOTLOADER_BUILD)
|
2019-04-11 05:01:49 -03:00
|
|
|
// setup watchdog to reset if main loop stops
|
2019-04-11 08:12:03 -03:00
|
|
|
if (AP_BoardConfig::watchdog_enabled()) {
|
2019-04-11 05:25:51 -03:00
|
|
|
stm32_watchdog_init();
|
|
|
|
}
|
2019-04-11 05:01:49 -03:00
|
|
|
|
2019-04-19 23:58:48 -03:00
|
|
|
if (hal.util->was_watchdog_reset()) {
|
|
|
|
AP::internalerror().error(AP_InternalError::error_t::watchdog_reset);
|
2019-05-09 08:15:58 -03:00
|
|
|
AP_HAL::Util::PersistentData &pd = hal.util->persistent_data;
|
2019-05-11 05:19:25 -03:00
|
|
|
AP::logger().Write("WDOG", "TimeUS,Task,IErr,IErrCnt,MavMsg,MavCmd,SemLine", "QbIIHHH",
|
2019-05-09 08:15:58 -03:00
|
|
|
AP_HAL::micros64(),
|
|
|
|
pd.scheduler_task,
|
|
|
|
pd.internal_errors,
|
2019-05-11 05:19:25 -03:00
|
|
|
pd.internal_error_count,
|
|
|
|
pd.last_mavlink_msgid,
|
|
|
|
pd.last_mavlink_cmd,
|
|
|
|
pd.semaphore_line);
|
2019-04-19 23:58:48 -03:00
|
|
|
}
|
2019-04-20 00:27:52 -03:00
|
|
|
#endif
|
2019-05-09 16:58:36 -03:00
|
|
|
|
2019-05-09 08:15:58 -03:00
|
|
|
schedulerInstance.watchdog_pat();
|
2019-04-19 23:58:48 -03:00
|
|
|
|
2019-05-09 08:15:58 -03:00
|
|
|
hal.scheduler->system_initialized();
|
|
|
|
|
|
|
|
thread_running = true;
|
|
|
|
chRegSetThreadName(SKETCHNAME);
|
|
|
|
|
|
|
|
/*
|
|
|
|
switch to high priority for main loop
|
|
|
|
*/
|
|
|
|
chThdSetPriority(APM_MAIN_PRIORITY);
|
2019-05-09 04:49:32 -03:00
|
|
|
|
2018-01-05 02:19:51 -04:00
|
|
|
while (true) {
|
|
|
|
g_callbacks->loop();
|
|
|
|
|
|
|
|
/*
|
2019-02-17 21:40:50 -04:00
|
|
|
give up 50 microseconds of time if the INS loop hasn't
|
2018-02-09 22:46:55 -04:00
|
|
|
called delay_microseconds_boost(), to ensure low priority
|
|
|
|
drivers get a chance to run. Calling
|
|
|
|
delay_microseconds_boost() means we have already given up
|
|
|
|
time from the main loop, so we don't need to do it again
|
|
|
|
here
|
2018-01-05 02:19:51 -04:00
|
|
|
*/
|
2018-10-29 19:20:33 -03:00
|
|
|
#ifndef HAL_DISABLE_LOOP_DELAY
|
2018-02-09 22:46:55 -04:00
|
|
|
if (!schedulerInstance.check_called_boost()) {
|
2019-02-17 21:40:50 -04:00
|
|
|
hal.scheduler->delay_microseconds(50);
|
2018-02-09 22:46:55 -04:00
|
|
|
}
|
2018-10-29 19:20:33 -03:00
|
|
|
#endif
|
2019-05-09 08:15:58 -03:00
|
|
|
schedulerInstance.watchdog_pat();
|
2018-01-05 02:19:51 -04:00
|
|
|
}
|
|
|
|
thread_running = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HAL_ChibiOS::run(int argc, char * const argv[], Callbacks* callbacks) const
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* System initializations.
|
|
|
|
* - ChibiOS HAL initialization, this also initializes the configured device drivers
|
|
|
|
* and performs the board-specific initializations.
|
|
|
|
* - Kernel initialization, the main() function becomes a thread and the
|
|
|
|
* RTOS is active.
|
|
|
|
*/
|
2018-03-01 20:46:30 -04:00
|
|
|
|
2018-03-06 18:41:03 -04:00
|
|
|
#ifdef HAL_USB_PRODUCT_ID
|
|
|
|
setup_usb_strings();
|
|
|
|
#endif
|
|
|
|
|
2018-03-01 20:46:30 -04:00
|
|
|
#ifdef HAL_STDOUT_SERIAL
|
2018-01-05 02:19:51 -04:00
|
|
|
//STDOUT Initialistion
|
|
|
|
SerialConfig stdoutcfg =
|
|
|
|
{
|
|
|
|
HAL_STDOUT_BAUDRATE,
|
|
|
|
0,
|
|
|
|
USART_CR2_STOP1_BITS,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
sdStart((SerialDriver*)&HAL_STDOUT_SERIAL, &stdoutcfg);
|
2018-03-01 20:46:30 -04:00
|
|
|
#endif
|
2018-01-05 02:19:51 -04:00
|
|
|
|
|
|
|
assert(callbacks);
|
|
|
|
g_callbacks = callbacks;
|
|
|
|
|
2018-08-29 10:11:48 -03:00
|
|
|
//Takeover main
|
|
|
|
main_loop();
|
2018-01-05 02:19:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const AP_HAL::HAL& AP_HAL::get_HAL() {
|
|
|
|
static const HAL_ChibiOS hal_chibios;
|
|
|
|
return hal_chibios;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|