Added debug routines.

Split the board specific code into a HAL API.
Added a POSIX HAL and hacked everything over to it.
master
Michael Hope 10 years ago
parent 6fc685bc2a
commit b0368f7af0
  1. 8
      .gitignore
  2. 28
      HACKING
  3. 44
      Makefile.am
  4. 15
      lib/timer.h
  5. 6
      roverif/board.h
  6. 197
      roverif/main.cc
  7. 29
      roverif/roverif.h
  8. 4
      roverif/start.cc
  9. 11
      roverif/supervisor.h

8
.gitignore vendored

@ -8,3 +8,11 @@
build
.deps
.dirstamp
Makefile.in
aclocal.m4
autom4te.cache/
configure
depcomp
install-sh
missing
*~

@ -45,3 +45,31 @@ Hardware interface
Events are generated by the HAL, timers, and other functions. Events
are recorded in a Switcher and then dispatched in priority order.
Event handlers are short and run to completion.
Status
------
Always out of date, but still.
STM32:
* Basic startup
* System tick driver
* GPIO driver
* USART driver (for GPS)
* PWM input driver (for reading the receiver demands)
* PWM output driver (for driving the servo)
* USB ACM driver
* Watchdog driver
* Serial log based debugging
roverif:
* Application level timers
* Switcher for dispatching events
* Status LED
* Supervisor
* Fail safe configuration
* Software fault fail safe
* GPS driver
* Accelerometer driver
* Gyro driver

@ -1,16 +1,16 @@
bin_PROGRAMS = blink.elf roverif.elf
bin_PROGRAMS = roverif.elf
blink_elf_SOURCES = \
experiments/blink.c
roverif_elf_SOURCES = \
roverif/main.cc \
roverif/init.cc \
roverif/start.cc \
roverif/pwmin.cc \
roverif/supervisor.cc
roverif/supervisor.cc \
roverif/hal-posix.cc
roverif_elf_LDADD = libnppilot.a libmaple.a libmaple-usb.a
#roverif_elf_LDADD = libnppilot.a libmaple.a libmaple-usb.a
roverif_elf_LDADD = libnppilot.a
check_PROGRAMS = \
tests/runner
@ -18,9 +18,12 @@ check_PROGRAMS = \
tests_runner_LDADD = libnppilot.a
lib_LIBRARIES = \
libmaple.a \
libmaple-usb.a \
libnppilot.a
libnppilot.a \
libplatform-posix.a
# libmaple.a \
# libmaple-usb.a \
#
libnppilot_a_SOURCES = \
lib/cobs.cc \
@ -28,6 +31,17 @@ libnppilot_a_SOURCES = \
lib/timer.cc \
lib/blinker.cc \
lib/switch.cc \
lib/debug.cc \
platform/posix/bitarray.cc \
platform/posix/timer.cc \
platform/posix/usblink.cc
libplatform_posix_a_SOURCES = \
platform/posix/bitarray.cc \
platform/posix/timer.cc \
platform/posix/usblink.cc
libplatform_stm32_a_SOURCES = \
platform/stm32/bitarray.cc \
platform/stm32/timer.cc \
platform/stm32/usblink.cc
@ -79,19 +93,21 @@ LIBMAPLE = $(srcdir)/external/libmaple
tests/runner.cc: $(wildcard $(srcdir)/tests/*.h)
$(srcdir)/external/cxxtest/bin/cxxtestgen --error-printer -o $@ $^
CROSS_COMPILE = arm-none-eabi-
#CROSS_COMPILE = arm-none-eabi-
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
OBJCOPY = $(CROSS_COMPILE)objcopy
FLAGS =
FLAGS += -O1 -g -Wall -fno-common -fno-section-anchors -fno-exceptions
FLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
#FLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
FLAGS += -I$(srcdir)/lib -I$(srcdir) -I$(srcdir)/external/cxxtest
FLAGS += -I$(LIBMAPLE)/libmaple/include -I$(LIBMAPLE)/libmaple -I$(LIBMAPLE)/libmaple/usb/usb_lib -I$(LIBMAPLE)/libmaple/stm32f1/include -I$(LIBMAPLE) -I$(srcdir)/platform/stm32
FLAGS += -mcpu=cortex-m3 -mthumb -save-temps=obj
FLAGS += -DMCU_STM32F103CB
FLAGS += -nostartfiles -T$(srcdir)/platform/coptercontrol/flash.ld
FLAGS += -save-temps=obj
#FLAGS += -I$(LIBMAPLE)/libmaple/include -I$(LIBMAPLE)/libmaple -I$(LIBMAPLE)/libmaple/usb/usb_lib -I$(LIBMAPLE)/libmaple/stm32f1/include -I$(LIBMAPLE) -I$(srcdir)/platform/stm32
#FLAGS += -mcpu=cortex-m3 -mthumb
#FLAGS += -DMCU_STM32F103CB
#FLAGS += -nostartfiles -T$(srcdir)/platform/coptercontrol/flash.ld
AM_CFLAGS = $(FLAGS) -std=gnu99
AM_CXXFLAGS = $(FLAGS) -std=gnu++0x -fno-rtti

@ -41,6 +41,7 @@ public:
/** Ticks all system timers, firing those that elapse. */
static void tick_all();
static void bind(Timer& timer, const Timer::Fixed& fixed);
private:
static const uint16_t Reserved = 0xFFFE;
@ -50,6 +51,18 @@ private:
uint16_t _remain;
};
#ifndef TIMER_IN_SECTIONS
#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
#define MAKE_TIMER(_name, _id, _period) \
Timer _name __attribute__((section(".timers"))); \
Timer::Fixed _name##_fixed \
= { _period - 1, _id };\
__attribute__((constructor)) void MACRO_CONCAT(init, __LINE__) () { \
Timer::bind(_name, _name##_fixed); }
#else
/**
* Make a timer called `_name` that triggers the thread `_id` and
* has the period `_period`. See Switcher::None and
@ -60,3 +73,5 @@ private:
Timer::Fixed _name##_fixed \
__attribute__((section(".timers.ro"))) \
= { _period - 1, _id };
#endif

@ -1,5 +1,11 @@
struct Board
{
static const int AHBClock = 72000000;
static const int APB1Clock = AHBClock / 2;
static const int APB2Clock = AHBClock / 1;
static const int LSIClock = 40000;
static const int DebugBaudRate = 115200;
static const int Ticks = 1000;
};

@ -1,155 +1,54 @@
#include <cstring>
#include <cstdint>
#include "libmaple/scb.h"
#include "libmaple/timer.h"
#include "libmaple/usart.h"
#include "libmaple/gpio.h"
#include "libmaple/iwdg.h"
#include "libmaple/usb_cdcacm.h"
#include "libmaple/usb/stm32f1/usb_reg_map.h"
#include "libmaple/systick.h"
#include <switcher.h>
#include <timer.h>
#include <cobs.h>
#include <usblink.h>
#include <platform/stm32/vectors.h>
#include <switch.h>
#include "supervisor.h"
#include <cstdio>
#include "roverif.h"
#include "protocol.h"
#include "pwmin.h"
#include "blinker.h"
volatile int stuck;
void init();
int main();
static PWMIn pwmin;
static Switcher switcher;
static USBLink usblink;
static COBSLink link;
static Blinker blinker;
static Supervisor supervisor;
void irq_timer4ch1()
{
timer_gen_reg_map& regs = *TIMER4->regs.gen;
pwmin.irq(0, regs.CCR1, &regs.CCER, TIMER_CCER_CC1P);
}
void irq_timer3ch2()
{
timer_gen_reg_map& regs = *TIMER3->regs.gen;
pwmin.irq(1, regs.CCR2, &regs.CCER, TIMER_CCER_CC2P);
}
void irq_timer3ch3()
{
timer_gen_reg_map& regs = *TIMER3->regs.gen;
pwmin.irq(2, regs.CCR3, &regs.CCER, TIMER_CCER_CC3P);
}
void irq_timer3ch4()
{
timer_gen_reg_map& regs = *TIMER3->regs.gen;
pwmin.irq(3, regs.CCR4, &regs.CCER, TIMER_CCER_CC4P);
}
void irq_timer2ch1()
{
timer_gen_reg_map& regs = *TIMER2->regs.gen;
pwmin.irq(4, regs.CCR1, &regs.CCER, TIMER_CCER_CC1P);
}
void irq_timer2ch2()
{
timer_gen_reg_map& regs = *TIMER2->regs.gen;
pwmin.irq(5, regs.CCR2, &regs.CCER, TIMER_CCER_CC2P);
}
static void put_hex(uint32_t v)
{
static const char* chars = "0123456789abcedf";
for (int i = 32-4; i >= 0; i -= 4) {
usart_putc(USART2, chars[(v >> i) & 0x0f]);
}
}
__attribute__((noinline))
static void _systick(uint32_t* sp)
{
if (++stuck == 1000) {
usart_putstr(USART2, "\r\nstuck at ");
put_hex(sp[6]);
usart_putstr(USART2, "\r\n");
}
switcher.trigger(SysTickID);
}
void systick()
{
uint32_t* sp;
asm volatile ("mov %0, sp" : "=r" (sp));
_systick(sp);
}
#include "hal.h"
PWMIn RoverIf::pwmin;
Switcher RoverIf::switcher;
USBLink RoverIf::usblink;
COBSLink RoverIf::link;
Blinker RoverIf::blinker;
Supervisor RoverIf::supervisor;
void COBSLink::write(const uint8_t* p, int length)
{
usblink.write(p, length);
RoverIf::usblink.write(p, length);
}
void Timer::dispatch(int id)
{
switcher.trigger(id);
RoverIf::switcher.trigger(id);
}
void COBSLink::dispatch(int id, const void* msg, int length)
{
usart_putstr(USART2, "COBSLink::dispatch\r\n");
Debug::info("COBSLink::dispatch");
}
static void heartbeat()
{
Protocol::Heartbeat msg = { .version = 1, .device_id = 2 };
link.send('h', &msg, sizeof(msg));
RoverIf::link.send('h', &msg, sizeof(msg));
}
void Blinker::update(bool level)
{
if (level) {
GPIOA_BASE->ODR &= ~(1 << 6);
} else {
GPIOA_BASE->ODR |= 1 << 6;
}
HAL::set_status_led(level);
}
void Supervisor::changed()
{
switch (supervisor.state()) {
case Supervisor::State::Remote:
blinker.set(0b100000101);
break;
case Supervisor::State::RemoteArmed:
blinker.set(0b100001101);
break;
case Supervisor::State::Pilot:
blinker.set(0b111111110);
break;
case Supervisor::State::Shutdown:
blinker.set(0b100000001);
break;
default:
blinker.set(0b101);
break;
}
static const uint16_t patterns[] = {
[State::None] = 0b101,
[State::Remote] = 0b100000101,
[State::RemoteArmed] = 0b100001101,
[State::Pilot] = 0b111111110,
[State::Shutdown] = 0b100000001,
};
RoverIf::blinker.set(patterns[(int)state()]);
}
static void tick()
@ -160,14 +59,8 @@ static void tick()
MAKE_TIMER(timer_expired, -1, Timer::Stopped);
MAKE_TIMER(blinker_tick, BlinkerID, 100);
static void poll()
void RoverIf::poll()
{
static int at;
static int direction = 1;
iwdg_feed();
stuck = 0;
Protocol::Inputs msg = { };
for (int i = 0; i < pwmin.count(); i++) {
@ -175,33 +68,17 @@ static void poll()
}
supervisor.set_remote(msg.channel, 6);
int ch1 = pwmin.value(0) - 8450;
int out = 0;
// 10550 8450 6300
timer_set_compare(TIMER4, 4, 8450 + ch1);
link.send('i', &msg, sizeof(msg));
if (usb_cdcacm_data_available()) {
uint8_t rx[32];
int got = usb_cdcacm_rx(rx, sizeof(rx));
link.feed(rx, got);
}
}
MAKE_TIMER(timer_heartbeat, HeartbeatID, 1000);
MAKE_TIMER(timer_poll, PollID, 20);
// 8296 counts as throttle cut
void Switcher::dispatch(int id)
{
switch (id) {
case BlinkerID:
blinker.tick();
RoverIf::blinker.tick();
break;
case SysTickID:
tick();
@ -210,10 +87,10 @@ void Switcher::dispatch(int id)
heartbeat();
break;
case PollID:
poll();
RoverIf::poll();
break;
case SupervisorID:
supervisor.expired();
RoverIf::supervisor.expired();
break;
default:
assert(false);
@ -221,31 +98,21 @@ void Switcher::dispatch(int id)
}
}
extern "C" usart_dev* __lm_enable_error_usart(void)
void RoverIf::init()
{
return USART2;
HAL::init();
}
__attribute__((noinline))
void stick()
void RoverIf::run()
{
for (;;) {}
}
HAL::start();
Debug::info("roverif: start");
int main()
{
blinker.set(0b101);
// stick();
usart_putstr(USART2, "\r\n\r\ngo\r\n");
usart_putudec(USART2, *(uint32_t*)0xE000ED00);
for (;;) {
switcher.next();
usblink.flush();
asm ("wfi");
HAL::wait();
}
return 0;
}

@ -1,3 +1,15 @@
#include <switcher.h>
#include <timer.h>
#include <cobs.h>
#include <usblink.h>
#include <switch.h>
#include "supervisor.h"
#include <debug.h>
#include "protocol.h"
#include "pwmin.h"
#include "blinker.h"
extern void systick();
void irq_timer4ch1();
void irq_timer3ch2();
@ -16,3 +28,20 @@ enum ThreadID {
PollID,
SupervisorID,
};
class RoverIf
{
public:
static void init();
static void run();
static void poll();
static void tick();
static PWMIn pwmin;
static Switcher switcher;
static USBLink usblink;
static COBSLink link;
static Blinker blinker;
static Supervisor supervisor;
};

@ -29,14 +29,14 @@ void _start()
memcpy(&__data_start, &__data_load, &__data_end - &__data_start);
memset(&__bss_start, 0, &__bss_end - &__bss_start);
init();
RoverIf::init();
for (init_function* i = &__init_array_start; i < &__init_array_end; i++) {
(**i)();
}
nvic_globalirq_enable();
main();
RoverIf::run();
for (;;) {
}

@ -16,7 +16,7 @@ public:
Remote,
RemoteArmed,
Pilot,
Shutdown
Shutdown,
};
Supervisor();
@ -28,6 +28,11 @@ public:
void expired();
static Timer remote_seen_;
static Timer::Fixed remote_seen__fixed;
static Timer pilot_seen_;
static Timer::Fixed pilot_seen__fixed;
private:
static const int LostThrottle = 8296;
static const int ThrottleChannel = 2;
@ -49,8 +54,4 @@ private:
Switch mode_;
static const Switch::Fixed mode_fixed_;
static Timer remote_seen_;
static Timer::Fixed remote_seen__fixed;
static Timer pilot_seen_;
static Timer::Fixed pilot_seen__fixed;
};

Loading…
Cancel
Save