소스 검색

Added debug routines.

Michael Hope 4 년 전
부모
커밋
6fc685bc2a
8개의 변경된 파일431개의 추가작업 그리고 21개의 파일을 삭제
  1. 89 0
      lib/debug.cc
  2. 21 0
      lib/debug.h
  3. 30 0
      platform/posix/timer.cc
  4. 19 0
      platform/posix/usblink.cc
  5. 82 0
      platform/stm32/start.cc
  6. 120 21
      roverif/hal-coptercontrol.cc
  7. 60 0
      roverif/hal-posix.cc
  8. 10 0
      roverif/hal.h

+ 89 - 0
lib/debug.cc 파일 보기

@@ -0,0 +1,89 @@
1
+#include <debug.h>
2
+#include <cassert>
3
+#include <cstdarg>
4
+
5
+void Debug::info(const char* pmsg, ...)
6
+{
7
+    print("info: ");
8
+
9
+    va_list args;
10
+    va_start(args, pmsg);
11
+    vprint(pmsg, args);
12
+    print("\r\n");
13
+}
14
+
15
+void Debug::error(const char* pmsg, ...)
16
+{
17
+    print("error: ");
18
+
19
+    va_list args;
20
+    va_start(args, pmsg);
21
+    vprint(pmsg, args);
22
+    print("\r\n");
23
+}
24
+
25
+void Debug::print(const char* pmsg)
26
+{
27
+    const char* pstop = pmsg + 100;
28
+
29
+    for (; *pmsg != 0 && pmsg < pstop; pmsg++) {
30
+        putch(*pmsg);
31
+    }
32
+}
33
+
34
+void Debug::vprint(const char* pmsg, va_list args)
35
+{
36
+    const char* pstop = pmsg + 100;
37
+
38
+    for (; *pmsg != 0 && pmsg < pstop; pmsg++) {
39
+        char ch = *pmsg;
40
+
41
+        if (ch == '%') {
42
+            ch = *++pmsg;
43
+
44
+            switch (ch) {
45
+            case '%':
46
+                putch(ch);
47
+                break;
48
+            case 'd':
49
+                printn(va_arg(args, int), 10, true);
50
+                break;
51
+            case 'u':
52
+                printn(va_arg(args, int), 10, false);
53
+                break;
54
+            case 'x':
55
+                printn(va_arg(args, int), 16, false);
56
+                break;
57
+            default:
58
+                assert(false);
59
+                break;
60
+            }
61
+        } else {
62
+            putch(ch);
63
+        }
64
+    }
65
+}
66
+
67
+void Debug::printn(int value, unsigned int base, bool is_signed)
68
+{
69
+    static const char digits[] = "0123456789abcdef";
70
+
71
+    if (is_signed && value < 0) {
72
+        putch('-');
73
+        value = -value;
74
+    }
75
+
76
+    unsigned int v = value;
77
+    char stack[11];
78
+    char* p = stack + sizeof(stack);
79
+    *--p = '\0';
80
+
81
+    do {
82
+        unsigned int next = v / base;
83
+        int remainder = v - next * base;
84
+        *--p = digits[remainder];
85
+        v = next;
86
+    } while (v != 0);
87
+
88
+    print(p);
89
+}

+ 21 - 0
lib/debug.h 파일 보기

@@ -0,0 +1,21 @@
1
+/*
2
+ * Debug message and assertion support.
3
+ */
4
+
5
+#pragma once
6
+
7
+#include <cstdarg>
8
+
9
+class Debug
10
+{
11
+public:
12
+    static void info(const char* pmsg, ...);
13
+    static void error(const char* pmsg, ...);
14
+
15
+private:
16
+    static void print(const char* pmsg);
17
+    static void printn(int value, unsigned int base, bool is_signed);
18
+    static void vprint(const char* pmsg, va_list args);
19
+
20
+    static void putch(char ch);
21
+};

+ 30 - 0
platform/posix/timer.cc 파일 보기

@@ -0,0 +1,30 @@
1
+#include "timer.h"
2
+#include "debug.h"
3
+
4
+struct Binding;
5
+
6
+struct Binding
7
+{
8
+    Timer* ptimer;
9
+    const Timer::Fixed* pfixed;
10
+};
11
+
12
+Binding _bindings[50];
13
+
14
+void Timer::tick_all()
15
+{
16
+    for (Binding* pbinding = _bindings; pbinding->ptimer != nullptr; pbinding++) {
17
+        pbinding->ptimer->tick(*pbinding->pfixed);
18
+    }
19
+}
20
+
21
+void Timer::bind(Timer& timer, const Timer::Fixed& fixed)
22
+{
23
+    for (Binding* pbinding = _bindings; true; pbinding++) {
24
+        if (pbinding->ptimer == nullptr) {
25
+            pbinding->ptimer = &timer;
26
+            pbinding->pfixed = &fixed;
27
+            break;
28
+        }
29
+    }
30
+}

+ 19 - 0
platform/posix/usblink.cc 파일 보기

@@ -0,0 +1,19 @@
1
+#include <cstdint>
2
+#include <algorithm>
3
+#include <cstring>
4
+
5
+#include "usblink.h"
6
+
7
+USBLink::USBLink()
8
+    : tx_()
9
+{
10
+}
11
+
12
+void USBLink::write(const uint8_t* data, int length)
13
+{
14
+}
15
+
16
+bool USBLink::flush()
17
+{
18
+    return true;
19
+}

+ 82 - 0
platform/stm32/start.cc 파일 보기

@@ -0,0 +1,82 @@
1
+#include <cstring>
2
+#include <cstdint>
3
+
4
+#include <vectors.h>
5
+
6
+#include "libmaple/nvic.h"
7
+#include "libmaple/usart.h"
8
+
9
+extern uint8_t __bss_start;
10
+extern uint8_t __bss_end;
11
+
12
+extern const uint8_t __data_load;
13
+extern uint8_t __data_start;
14
+extern uint8_t __data_end;
15
+
16
+typedef void (*init_function)(void);
17
+
18
+extern init_function __init_array_start;
19
+extern init_function __init_array_end;
20
+
21
+extern "C" int main(void);
22
+
23
+/** Main function.  Called by the startup code. */
24
+void _start()
25
+{
26
+  nvic_globalirq_disable();
27
+  nvic_init((uint32_t)&vectors, 0);
28
+
29
+  memcpy(&__data_start, &__data_load, &__data_end - &__data_start);
30
+  memset(&__bss_start, 0, &__bss_end - &__bss_start);
31
+
32
+  for (init_function* i = &__init_array_start; i < &__init_array_end; i++) {
33
+      (**i)();
34
+  }
35
+
36
+  nvic_globalirq_enable();
37
+  main();
38
+
39
+  for (;;) {
40
+  }
41
+}
42
+
43
+__attribute__((naked))
44
+static void irq_default()
45
+{
46
+  for (;;) {}
47
+}
48
+
49
+__attribute__((section(".vectors")))
50
+const struct Vectors vectors =
51
+{
52
+  .stack_top = &__stack_top,
53
+  .reset = _start,
54
+
55
+  irq_default, irq_default, irq_default, irq_default, irq_default,
56
+  {},
57
+  .svc = irq_default,
58
+  irq_default, 0, irq_default,
59
+
60
+  irq_default,
61
+
62
+  irq_default,
63
+  irq_default,
64
+  irq_default,
65
+  irq_default,
66
+  irq_default,
67
+  irq_default,
68
+  irq_default,
69
+  irq_default,
70
+  irq_default,
71
+  irq_default,
72
+  irq_default,
73
+  irq_default,
74
+  irq_default,
75
+  irq_default,
76
+  irq_default,
77
+  irq_default,
78
+  irq_default,
79
+  irq_default,
80
+  irq_default,
81
+  irq_default,
82
+};

roverif/init.cc → roverif/hal-coptercontrol.cc 파일 보기

@@ -1,16 +1,104 @@
1
-#include "libmaple/rcc.h"
2
-#include "libmaple/gpio.h"
3
-#include "libmaple/systick.h"
4
-#include "libmaple/flash.h"
5
-#include "libmaple/usart.h"
6
-#include "libmaple/delay.h"
1
+/*
2
+ * CopterControl specific implementation.
3
+ */
4
+
5
+#include "roverif.h"
6
+
7
+#include "libmaple/scb.h"
7 8
 #include "libmaple/timer.h"
9
+#include "libmaple/usart.h"
10
+#include "libmaple/gpio.h"
8 11
 #include "libmaple/iwdg.h"
9 12
 #include "libmaple/usb_cdcacm.h"
10 13
 #include "libmaple/usb/stm32f1/usb_reg_map.h"
14
+#include "libmaple/systick.h"
11 15
 
12
-#include "board.h"
13
-#include "roverif.h"
16
+#include <platform/stm32/vectors.h>
17
+
18
+volatile int stuck;
19
+
20
+
21
+void irq_timer4ch1()
22
+{
23
+    timer_gen_reg_map& regs = *TIMER4->regs.gen;
24
+    RoverIf::pwmin.irq(0, regs.CCR1, &regs.CCER, TIMER_CCER_CC1P);
25
+}
26
+
27
+void irq_timer3ch2()
28
+{
29
+    timer_gen_reg_map& regs = *TIMER3->regs.gen;
30
+    RoverIf::pwmin.irq(1, regs.CCR2, &regs.CCER, TIMER_CCER_CC2P);
31
+}
32
+
33
+void irq_timer3ch3()
34
+{
35
+    timer_gen_reg_map& regs = *TIMER3->regs.gen;
36
+    RoverIf::pwmin.irq(2, regs.CCR3, &regs.CCER, TIMER_CCER_CC3P);
37
+}
38
+
39
+void irq_timer3ch4()
40
+{
41
+    timer_gen_reg_map& regs = *TIMER3->regs.gen;
42
+    RoverIf::pwmin.irq(3, regs.CCR4, &regs.CCER, TIMER_CCER_CC4P);
43
+}
44
+
45
+void irq_timer2ch1()
46
+{
47
+    timer_gen_reg_map& regs = *TIMER2->regs.gen;
48
+    RoverIf::pwmin.irq(4, regs.CCR1, &regs.CCER, TIMER_CCER_CC1P);
49
+}
50
+
51
+void irq_timer2ch2()
52
+{
53
+    timer_gen_reg_map& regs = *TIMER2->regs.gen;
54
+    RoverIf::pwmin.irq(5, regs.CCR2, &regs.CCER, TIMER_CCER_CC2P);
55
+}
56
+
57
+__attribute__((noinline))
58
+static void _systick(uint32_t* sp)
59
+{
60
+    RoverIf::switcher.trigger(SysTickID);
61
+
62
+    if (++stuck == 1000) {
63
+        Debug::error("Stuck at %x", sp[6]);
64
+    }
65
+}
66
+
67
+void systick()
68
+{
69
+    uint32_t* sp;
70
+    asm volatile ("mov %0, sp" : "=r" (sp));
71
+    _systick(sp);
72
+}
73
+
74
+void RoverIf::set_status_led(bool level)
75
+{
76
+    if (level) {
77
+        GPIOA_BASE->ODR &= ~(1 << 6);
78
+    } else {
79
+        GPIOA_BASE->ODR |= 1 << 6;
80
+    }
81
+}
82
+
83
+void RoverIf::poll_hal()
84
+{
85
+    if (usb_cdcacm_data_available()) {
86
+        uint8_t rx[32];
87
+        int got = usb_cdcacm_rx(rx, sizeof(rx));
88
+        link.feed(rx, got);
89
+    }
90
+
91
+    iwdg_feed();
92
+}    
93
+
94
+void RoverIf::wait()
95
+{
96
+    asm ("wfi");
97
+}
98
+
99
+void Debug::putch(char ch)
100
+{
101
+}
14 102
 
15 103
 static void init_usb()
16 104
 {
@@ -146,30 +234,41 @@ static void init_timers()
146 234
     timer_attach_interrupt(TIMER2, TIMER_CC2_INTERRUPT, irq_timer2ch2);
147 235
 }
148 236
 
149
-void init()
237
+static void init_debug_usart()
150 238
 {
151
-    flash_enable_prefetch();
152
-    flash_set_latency(FLASH_WAIT_STATE_2);
239
+    usart_init(USART3);
240
+    usart_set_baud_rate(USART3, Board::APB1Clock, Board::DebugBaudRate);
241
+    usart_enable(USART3);
242
+
243
+    gpio_set_mode(GPIOA, 2, GPIO_AF_OUTPUT_PP);
244
+    gpio_set_mode(GPIOA, 6, GPIO_OUTPUT_PP);
245
+}
153 246
 
247
+static void init_clocks()
248
+{
154 249
     rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9);
155 250
     rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
156 251
     rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2);
157 252
     rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1);
253
+}
158 254
 
159
-    systick_init(72000 - 1);
160
-
161
-    gpio_init_all();
255
+void RoverIf::init_hal()
256
+{
257
+    /* Reset after 500 ms */
258
+    iwdg_init(IWDG_PRE_32, Board::LSIClock / 32 * 2000/1000);
162 259
 
163
-    usart_init(USART2);
164
-    usart_set_baud_rate(USART2, 72000000/2, 115200);
165
-    usart_enable(USART2);
260
+    flash_enable_prefetch();
261
+    flash_set_latency(FLASH_WAIT_STATE_2);
262
+    init_clocks();
263
+    init_debug_usart();
166 264
 
167
-    gpio_set_mode(GPIOA, 2, GPIO_AF_OUTPUT_PP);
168
-    gpio_set_mode(GPIOA, 6, GPIO_OUTPUT_PP);
265
+    systick_init(Board::AHBClock / Board::Ticks - 1);
169 266
 
267
+    gpio_init_all();
170 268
     init_timers();
171 269
     init_usb();
270
+}
172 271
 
173
-    /* Reset after 500 ms */
174
-    iwdg_init(IWDG_PRE_32, 40000 / 32 * 2000/1000);
272
+void RoverIf::start_hal()
273
+{
175 274
 }

+ 60 - 0
roverif/hal-posix.cc 파일 보기

@@ -0,0 +1,60 @@
1
+#include "roverif.h"
2
+#include "hal.h"
3
+#include "board.h"
4
+
5
+#include <cstdio>
6
+#include <time.h>
7
+
8
+static struct timespec _epoch;
9
+static int64_t _ticks;
10
+
11
+void HAL::init()
12
+{
13
+}
14
+
15
+void HAL::start()
16
+{
17
+    clock_gettime(CLOCK_MONOTONIC, &_epoch);
18
+}
19
+
20
+void HAL::poll()
21
+{
22
+}
23
+
24
+void HAL::wait()
25
+{
26
+    struct timespec now;
27
+    clock_gettime(CLOCK_MONOTONIC, &now);
28
+    int64_t elapsed = (now.tv_sec - _epoch.tv_sec) * Board::Ticks + (now.tv_nsec - _epoch.tv_nsec) / (1000000000 / Board::Ticks);
29
+
30
+    if (elapsed == _ticks) {
31
+        struct timespec sleep_for = { 0, 1000000 };
32
+        nanosleep(&sleep_for, NULL);
33
+    } else {
34
+        _ticks++;
35
+        RoverIf::switcher.trigger(SysTickID);
36
+        fflush(stdout);
37
+    }
38
+}
39
+
40
+void HAL::set_status_led(bool on)
41
+{
42
+    if (on) {
43
+        ::putchar('*');
44
+    } else {
45
+        ::putchar('.');
46
+    }
47
+}
48
+
49
+void Debug::putch(char ch)
50
+{
51
+    ::putchar(ch);
52
+}
53
+
54
+int main()
55
+{
56
+    RoverIf::init();
57
+    RoverIf::run();
58
+
59
+    return 0;
60
+}

+ 10 - 0
roverif/hal.h 파일 보기

@@ -0,0 +1,10 @@
1
+class HAL
2
+{
3
+public:
4
+    static void init();
5
+    static void start();
6
+    static void poll();
7
+    static void wait();
8
+
9
+    static void set_status_led(bool on);
10
+};