Skip to content

Commit dc0fc40

Browse files
Initial Qemu target
1 parent 4c1aa10 commit dc0fc40

19 files changed

+955
-3
lines changed

src/main.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ void TOUCH_Handler(); // temporarily in main()
3636
void VIDEO_Update();
3737
void PAGE_Test();
3838

39-
#ifdef TEST
40-
#define main _main
41-
#endif
39+
int main() __attribute__((weak));
4240

4341
#ifndef DUMP_BOOTLOADER
4442
int main() {

src/target/qemu/.power.c.swp

4 KB
Binary file not shown.

src/target/qemu/.target_main.c.swp

12 KB
Binary file not shown.

src/target/qemu/Makefile.inc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
FILESYSTEMS := common base_fonts 320x240x16
2+
3+
SCREENSIZE := 320x240x16
4+
FONTS = filesystem/$(FILESYSTEM)/media/15ascii.fon \
5+
filesystem/$(FILESYSTEM)/media/23bold.fon
6+
7+
ifndef BUILD_TARGET
8+
CROSS = arm-none-eabi-
9+
10+
ALL = $(LIBOPENCM3) $(TARGET).bin
11+
12+
NUM_MODELS ?= 10
13+
14+
LINKFILE = $(SDIR)/target/$(TARGET)/$(TARGET).ld
15+
LIBOPENCM3 = $(SDIR)/libopencm3/lib/libopencm3_stm32f1.a
16+
17+
SRC_C := $(wildcard $(SDIR)/target/$(TARGET)/*.c) \
18+
$(wildcard $(SDIR)/target/common/stm32/*.c) \
19+
$(wildcard $(SDIR)/target/common/filesystems/*.c) \
20+
$(wildcard $(SDIR)/target/common/filesystems/devofs/*.c) \
21+
$(wildcard $(SDIR)/target/common/filesystems/petit_fat/*.c) \
22+
$(wildcard $(SDIR)/target/common/devo/msc2/*.c) \
23+
$(wildcard $(SDIR)/target/common/devo/msc2/lib/*.c) \
24+
$(wildcard $(SDIR)/target/common/devo/hid/*.c) \
25+
$(wildcard $(SDIR)/target/common/devo/protocol/*.c) \
26+
$(wildcard $(SDIR)/target/common/devo/uart.c)
27+
28+
SRC_C := $(filter-out $(SDIR)/target/common/stm32/spi_flash.c, $(SRC_C))
29+
30+
CFLAGS = -D"assert_param(x)=" -DSTM32F10X_HD -DSTM32F1 -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fdata-sections -ffunction-sections -I$(SDIR)/target/common/devo/msc2/lib -I$(SDIR)/target/common/devo/msc2 -I$(SDIR)/libopencm3/include -I$(SDIR)/target/common/filesystems -fno-builtin-printf -Os --specs=nano.specs
31+
MODULE_FLAGS = -fno-builtin
32+
33+
LFLAGS = -nostartfiles -Wl,-gc-sections -Wl,-Map=$(TARGET).map,--cref -lc -lnosys -L$(SDIR) -Lobjs/$(TARGET)
34+
LFLAGS2 = -Wl,-T$(LINKFILE)
35+
36+
37+
else #BUILD_TARGET
38+
39+
$(TARGET).bin: $(TARGET).elf
40+
$(CP) -O binary $< $@
41+
$(DUMP) -S $< > $(TARGET).list
42+
43+
$(LIBOPENCM3):
44+
+$(MAKE) -C $(SDIR)/libopencm3 TARGETS=stm32/f1 lib
45+
46+
47+
endif #BUILD_TARGET

src/target/qemu/backlight.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
This project is free software: you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation, either version 3 of the License, or
5+
(at your option) any later version.
6+
7+
Deviation is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with Deviation. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
#include <libopencm3/stm32/gpio.h>
17+
#include <libopencm3/stm32/rcc.h>
18+
#include <libopencm3/stm32/timer.h>
19+
#include "common.h"
20+
21+
// FIXME introduce constants for Timer (TIM4), compare (TIM_Oc4)
22+
// timer clock (RCC_APB1ENR_TIM4EN), Port (GPIOB), Pin (GPIO9)
23+
// Port clock RCC_APB2ENR_IOPBEN
24+
25+
void BACKLIGHT_Init()
26+
{
27+
// Pin PB9, Timer 4 channel 4
28+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
29+
//Turn off backlight
30+
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
31+
GPIO_CNF_INPUT_FLOAT, GPIO9);
32+
33+
//Configure Backlight PWM
34+
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM4EN);
35+
timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT,
36+
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
37+
timer_set_period(TIM4, 0x2CF);
38+
timer_set_prescaler(TIM4, 0);
39+
timer_generate_event(TIM4, TIM_EGR_UG);
40+
//timer_set_repetition_counter(TIM3, 0);
41+
timer_set_oc_mode(TIM4, TIM_OC4, TIM_OCM_PWM1);
42+
timer_enable_oc_preload(TIM4, TIM_OC4);
43+
44+
timer_set_oc_polarity_high(TIM4, TIM_OC4);
45+
timer_enable_oc_output(TIM4, TIM_OC4);
46+
47+
timer_enable_preload(TIM4);
48+
}
49+
50+
void BACKLIGHT_Brightness(unsigned brightness)
51+
{
52+
timer_disable_counter(TIM4);
53+
if (brightness == 0) {
54+
// Turn off Backlight
55+
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
56+
GPIO_CNF_INPUT_FLOAT, GPIO9);
57+
} else if(brightness > 9) {
58+
// Turn on Backlight full
59+
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
60+
GPIO_CNF_OUTPUT_PUSHPULL, GPIO9);
61+
gpio_set(GPIOB, GPIO9);
62+
} else {
63+
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
64+
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
65+
u32 duty_cycle = 720 * brightness / 10 ;
66+
timer_set_oc_value(TIM4, TIM_OC4, duty_cycle);
67+
timer_enable_counter(TIM4);
68+
}
69+
}
70+
71+
void LCD_Contrast(unsigned contrast)
72+
{
73+
(void)contrast; // dummy method for devo8. Only valid in devo10 now
74+
}
75+

src/target/qemu/capabilities.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifdef CHANDEF
2+
CHANDEF(AILERON)
3+
CHANDEF(ELEVATOR)
4+
CHANDEF(THROTTLE)
5+
CHANDEF(RUDDER)
6+
CHANDEF(AUX4)
7+
CHANDEF(AUX5)
8+
CHANDEF(AUX6)
9+
CHANDEF(AUX7)
10+
CHANDEF(SWA0)
11+
CHANDEF(SWA1)
12+
CHANDEF(SWB0)
13+
CHANDEF(SWB1)
14+
CHANDEF(SWC0)
15+
CHANDEF(SWC1)
16+
CHANDEF(SWC2)
17+
CHANDEF(SWD0)
18+
CHANDEF(SWD1)
19+
CHANDEF(SWE0)
20+
CHANDEF(SWE1)
21+
CHANDEF(SWE2)
22+
CHANDEF(SWF0)
23+
CHANDEF(SWF1)
24+
CHANDEF(SWG0)
25+
CHANDEF(SWG1)
26+
CHANDEF(SWG2)
27+
CHANDEF(SWH0)
28+
CHANDEF(SWH1)
29+
#endif
30+
31+
#ifdef UNDEF_INP
32+
#define INP_RUD_DR0 INP_SWA0
33+
#define INP_RUD_DR1 INP_SWA1
34+
#define INP_ELE_DR0 INP_SWB0
35+
#define INP_ELE_DR1 INP_SWB1
36+
#define INP_AIL_DR0 INP_SWC0
37+
#define INP_AIL_DR1 INP_SWC1
38+
#define INP_FMOD0 INP_SWD0
39+
#define INP_MIX0 INP_SWE0
40+
#define INP_MIX1 INP_SWE1
41+
#define INP_MIX2 INP_SWE2
42+
#define INP_GEAR0 INP_SWF0
43+
#define INP_GEAR1 INP_SWF1
44+
#endif
45+
46+
47+
#ifdef BUTTONDEF
48+
BUTTONDEF(TRIM_LV_NEG) /* LEFT-VERTICAL */
49+
BUTTONDEF(TRIM_LV_POS)
50+
BUTTONDEF(TRIM_RV_NEG) /* RIGHT-VERTICAL */
51+
BUTTONDEF(TRIM_RV_POS)
52+
BUTTONDEF(TRIM_LH_NEG) /* LEFT-HORIZONTAL */
53+
BUTTONDEF(TRIM_LH_POS)
54+
BUTTONDEF(TRIM_RH_NEG) /* RIGHT-HORIZONTAL */
55+
BUTTONDEF(TRIM_RH_POS)
56+
BUTTONDEF(LEFT)
57+
BUTTONDEF(RIGHT)
58+
BUTTONDEF(DOWN)
59+
BUTTONDEF(UP)
60+
BUTTONDEF(ENTER)
61+
BUTTONDEF(EXIT)
62+
#endif

src/target/qemu/channels.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
This project is free software: you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation, either version 3 of the License, or
5+
(at your option) any later version.
6+
7+
Deviation is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with Deviation. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
#include <libopencm3/stm32/rcc.h>
16+
#include <libopencm3/stm32/gpio.h>
17+
#include "common.h"
18+
#include "mixer.h"
19+
#include "config/tx.h"
20+
#include "../common/devo/devo.h"
21+
22+
//Order is MODE1: AIL, ELE, THR, RUD, LeftDial, Right Dial, Left Shoulder, Right Shoulder, Vdd, Voltage
23+
// PA0 PA1, PA2, PA3, PA5, PA6, PB0 PA4, PB1
24+
const u8 adc_chan_sel[NUM_ADC_CHANNELS] =
25+
{0, 1, 2, 3, 5, 6, 8, 4, 16, 9};
26+
27+
void CHAN_Init()
28+
{
29+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
30+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
31+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
32+
ADC_Init();
33+
34+
/* configure channels for analog */
35+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
36+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
37+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO2);
38+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO3);
39+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4);
40+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO5);
41+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO6);
42+
/* Enable Voltage measurement */
43+
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
44+
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
45+
46+
/* configure switches for digital I/O */
47+
gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
48+
GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
49+
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9);
50+
gpio_set(GPIOC,
51+
GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
52+
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9);
53+
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO8);
54+
gpio_set(GPIOA, GPIO8);
55+
}
56+
57+
s32 CHAN_ReadRawInput(int channel)
58+
{
59+
s32 value = 0;
60+
switch(channel) {
61+
case INP_AILERON: value = adc_array_raw[0]; break; // bug fix: right vertical
62+
case INP_ELEVATOR: value = adc_array_raw[1]; break; // bug fix: right horizon
63+
case INP_THROTTLE: value = adc_array_raw[2]; break; // bug fix: left horizon
64+
case INP_RUDDER: value = adc_array_raw[3]; break; // bug fix: left vertical
65+
case INP_AUX4: value = adc_array_raw[4]; break;
66+
case INP_AUX5: value = adc_array_raw[5]; break;
67+
case INP_AUX6: value = adc_array_raw[6]; break;
68+
case INP_AUX7: value = adc_array_raw[7]; break;
69+
case INP_SWA0: value = gpio_get(GPIOC, GPIO0); break;
70+
case INP_SWA1: value = ! gpio_get(GPIOC, GPIO0); break;
71+
case INP_SWB0: value = gpio_get(GPIOC, GPIO1); break;
72+
case INP_SWB1: value = ! gpio_get(GPIOC, GPIO1); break;
73+
case INP_SWC0: value = ! gpio_get(GPIOC, GPIO2); break;
74+
case INP_SWC1: value = (gpio_get(GPIOC, GPIO2) && gpio_get(GPIOC, GPIO3)); break;
75+
case INP_SWC2: value = ! gpio_get(GPIOC, GPIO3); break;
76+
case INP_SWD0: value = gpio_get(GPIOC, GPIO6); break;
77+
case INP_SWD1: value = ! gpio_get(GPIOC, GPIO6); break;
78+
case INP_SWE0: value = ! gpio_get(GPIOC, GPIO4); break;
79+
case INP_SWE1: value = (gpio_get(GPIOC, GPIO4) && gpio_get(GPIOC, GPIO5)); break;
80+
case INP_SWE2: value = ! gpio_get(GPIOC, GPIO5); break;
81+
case INP_SWF0: value = gpio_get(GPIOC, GPIO7); break;
82+
case INP_SWF1: value = ! gpio_get(GPIOC, GPIO7); break;
83+
case INP_SWG0: value = ! gpio_get(GPIOC, GPIO8); break;
84+
case INP_SWG1: value = (gpio_get(GPIOC, GPIO8) && gpio_get(GPIOC, GPIO9)); break;
85+
case INP_SWG2: value = ! gpio_get(GPIOC, GPIO9); break;
86+
case INP_SWH0: value = gpio_get(GPIOA, GPIO8); break;
87+
case INP_SWH1: value = ! gpio_get(GPIOA, GPIO8); break;
88+
}
89+
return value;
90+
}
91+
s32 CHAN_ReadInput(int channel)
92+
{
93+
s32 value = CHAN_ReadRawInput(channel);
94+
if(channel <= INP_HAS_CALIBRATION) {
95+
s32 max = Transmitter.calibration[channel - 1].max;
96+
s32 min = Transmitter.calibration[channel - 1].min;
97+
s32 zero = Transmitter.calibration[channel - 1].zero;
98+
if(! zero) {
99+
//If this input doesn't have a zero, calculate from max/min
100+
zero = ((u32)max + min) / 2;
101+
}
102+
// Derate min and max by 1% to ensure we can get all the way to 100%
103+
max = (max - zero) * 99 / 100;
104+
min = (min - zero) * 99 / 100;
105+
if(value >= zero) {
106+
value = (value - zero) * CHAN_MAX_VALUE / max;
107+
} else {
108+
value = (value - zero) * CHAN_MIN_VALUE / min;
109+
}
110+
//Bound output
111+
if (value > CHAN_MAX_VALUE)
112+
value = CHAN_MAX_VALUE;
113+
if (value < CHAN_MIN_VALUE)
114+
value = CHAN_MIN_VALUE;
115+
} else {
116+
value = value ? CHAN_MAX_VALUE : CHAN_MIN_VALUE;
117+
}
118+
if (channel == INP_AILERON || channel == INP_ELEVATOR ||
119+
channel == INP_THROTTLE || channel == INP_RUDDER)
120+
{
121+
value = -value;
122+
}
123+
return value;
124+
}

src/target/qemu/lcd.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
This project is free software: you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation, either version 3 of the License, or
5+
(at your option) any later version.
6+
7+
Deviation is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with Deviation. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
#include <libopencm3/stm32/gpio.h>
16+
#include <libopencm3/stm32/rcc.h>
17+
#include <libopencm3/stm32/fsmc.h>
18+
#include "common.h"
19+
#include "lcd.h"
20+
21+
u8 screen_flip;
22+
const struct lcdtype *disp_type;
23+
24+
void lcd_cmd(uint8_t addr, uint8_t data)
25+
{
26+
}
27+
28+
void lcd_set_pos(unsigned int x0, unsigned int y0)
29+
{
30+
}
31+
32+
void LCD_DrawPixel(unsigned int color)
33+
{
34+
}
35+
36+
void LCD_DrawPixelXY(unsigned int x, unsigned int y, unsigned int color)
37+
{
38+
}
39+
40+
void LCD_DrawStart(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, enum DrawDir dir)
41+
{
42+
}
43+
44+
void LCD_DrawStop(void)
45+
{
46+
}
47+
48+
void LCD_Sleep()
49+
{
50+
}
51+
52+
void LCD_Init()
53+
{
54+
}
55+

0 commit comments

Comments
 (0)