Skip to content

Commit

Permalink
Initial qemu target
Browse files Browse the repository at this point in the history
  • Loading branch information
PhracturedBlue committed Jan 9, 2019
1 parent e8a540e commit f4aa3bd
Show file tree
Hide file tree
Showing 19 changed files with 955 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ void TOUCH_Handler(); // temporarily in main()
void VIDEO_Update();
void PAGE_Test();

#ifdef TEST
#define main _main
#endif
int main() __attribute__((weak));

#ifndef DUMP_BOOTLOADER
int main() {
Expand Down
Binary file added src/target/qemu/.power.c.swp
Binary file not shown.
Binary file added src/target/qemu/.target_main.c.swp
Binary file not shown.
47 changes: 47 additions & 0 deletions src/target/qemu/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FILESYSTEMS := common base_fonts 320x240x16

SCREENSIZE := 320x240x16
FONTS = filesystem/$(FILESYSTEM)/media/15ascii.fon \
filesystem/$(FILESYSTEM)/media/23bold.fon

ifndef BUILD_TARGET
CROSS = arm-none-eabi-

ALL = $(LIBOPENCM3) $(TARGET).bin

NUM_MODELS ?= 10

LINKFILE = $(SDIR)/target/$(TARGET)/$(TARGET).ld
LIBOPENCM3 = $(SDIR)/libopencm3/lib/libopencm3_stm32f1.a

SRC_C := $(wildcard $(SDIR)/target/$(TARGET)/*.c) \
$(wildcard $(SDIR)/target/common/stm32/*.c) \
$(wildcard $(SDIR)/target/common/filesystems/*.c) \
$(wildcard $(SDIR)/target/common/filesystems/devofs/*.c) \
$(wildcard $(SDIR)/target/common/filesystems/petit_fat/*.c) \
$(wildcard $(SDIR)/target/common/devo/msc2/*.c) \
$(wildcard $(SDIR)/target/common/devo/msc2/lib/*.c) \
$(wildcard $(SDIR)/target/common/devo/hid/*.c) \
$(wildcard $(SDIR)/target/common/devo/protocol/*.c) \
$(wildcard $(SDIR)/target/common/devo/uart.c)

SRC_C := $(filter-out $(SDIR)/target/common/stm32/spi_flash.c, $(SRC_C))

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
MODULE_FLAGS = -fno-builtin

LFLAGS = -nostartfiles -Wl,-gc-sections -Wl,-Map=$(TARGET).map,--cref -lc -lnosys -L$(SDIR) -Lobjs/$(TARGET)
LFLAGS2 = -Wl,-T$(LINKFILE)


else #BUILD_TARGET

$(TARGET).bin: $(TARGET).elf
$(CP) -O binary $< $@
$(DUMP) -S $< > $(TARGET).list

$(LIBOPENCM3):
+$(MAKE) -C $(SDIR)/libopencm3 TARGETS=stm32/f1 lib


endif #BUILD_TARGET
75 changes: 75 additions & 0 deletions src/target/qemu/backlight.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
This project 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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
*/

#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include "common.h"

// FIXME introduce constants for Timer (TIM4), compare (TIM_Oc4)
// timer clock (RCC_APB1ENR_TIM4EN), Port (GPIOB), Pin (GPIO9)
// Port clock RCC_APB2ENR_IOPBEN

void BACKLIGHT_Init()
{
// Pin PB9, Timer 4 channel 4
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
//Turn off backlight
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO9);

//Configure Backlight PWM
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM4EN);
timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT,
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_period(TIM4, 0x2CF);
timer_set_prescaler(TIM4, 0);
timer_generate_event(TIM4, TIM_EGR_UG);
//timer_set_repetition_counter(TIM3, 0);
timer_set_oc_mode(TIM4, TIM_OC4, TIM_OCM_PWM1);
timer_enable_oc_preload(TIM4, TIM_OC4);

timer_set_oc_polarity_high(TIM4, TIM_OC4);
timer_enable_oc_output(TIM4, TIM_OC4);

timer_enable_preload(TIM4);
}

void BACKLIGHT_Brightness(unsigned brightness)
{
timer_disable_counter(TIM4);
if (brightness == 0) {
// Turn off Backlight
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO9);
} else if(brightness > 9) {
// Turn on Backlight full
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO9);
gpio_set(GPIOB, GPIO9);
} else {
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
u32 duty_cycle = 720 * brightness / 10 ;
timer_set_oc_value(TIM4, TIM_OC4, duty_cycle);
timer_enable_counter(TIM4);
}
}

void LCD_Contrast(unsigned contrast)
{
(void)contrast; // dummy method for devo8. Only valid in devo10 now
}

62 changes: 62 additions & 0 deletions src/target/qemu/capabilities.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifdef CHANDEF
CHANDEF(AILERON)
CHANDEF(ELEVATOR)
CHANDEF(THROTTLE)
CHANDEF(RUDDER)
CHANDEF(AUX4)
CHANDEF(AUX5)
CHANDEF(AUX6)
CHANDEF(AUX7)
CHANDEF(SWA0)
CHANDEF(SWA1)
CHANDEF(SWB0)
CHANDEF(SWB1)
CHANDEF(SWC0)
CHANDEF(SWC1)
CHANDEF(SWC2)
CHANDEF(SWD0)
CHANDEF(SWD1)
CHANDEF(SWE0)
CHANDEF(SWE1)
CHANDEF(SWE2)
CHANDEF(SWF0)
CHANDEF(SWF1)
CHANDEF(SWG0)
CHANDEF(SWG1)
CHANDEF(SWG2)
CHANDEF(SWH0)
CHANDEF(SWH1)
#endif

#ifdef UNDEF_INP
#define INP_RUD_DR0 INP_SWA0
#define INP_RUD_DR1 INP_SWA1
#define INP_ELE_DR0 INP_SWB0
#define INP_ELE_DR1 INP_SWB1
#define INP_AIL_DR0 INP_SWC0
#define INP_AIL_DR1 INP_SWC1
#define INP_FMOD0 INP_SWD0
#define INP_MIX0 INP_SWE0
#define INP_MIX1 INP_SWE1
#define INP_MIX2 INP_SWE2
#define INP_GEAR0 INP_SWF0
#define INP_GEAR1 INP_SWF1
#endif


#ifdef BUTTONDEF
BUTTONDEF(TRIM_LV_NEG) /* LEFT-VERTICAL */
BUTTONDEF(TRIM_LV_POS)
BUTTONDEF(TRIM_RV_NEG) /* RIGHT-VERTICAL */
BUTTONDEF(TRIM_RV_POS)
BUTTONDEF(TRIM_LH_NEG) /* LEFT-HORIZONTAL */
BUTTONDEF(TRIM_LH_POS)
BUTTONDEF(TRIM_RH_NEG) /* RIGHT-HORIZONTAL */
BUTTONDEF(TRIM_RH_POS)
BUTTONDEF(LEFT)
BUTTONDEF(RIGHT)
BUTTONDEF(DOWN)
BUTTONDEF(UP)
BUTTONDEF(ENTER)
BUTTONDEF(EXIT)
#endif
124 changes: 124 additions & 0 deletions src/target/qemu/channels.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
This project 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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include "common.h"
#include "mixer.h"
#include "config/tx.h"
#include "../common/devo/devo.h"

//Order is MODE1: AIL, ELE, THR, RUD, LeftDial, Right Dial, Left Shoulder, Right Shoulder, Vdd, Voltage
// PA0 PA1, PA2, PA3, PA5, PA6, PB0 PA4, PB1
const u8 adc_chan_sel[NUM_ADC_CHANNELS] =
{0, 1, 2, 3, 5, 6, 8, 4, 16, 9};

void CHAN_Init()
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
ADC_Init();

/* configure channels for analog */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO2);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO3);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO4);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO5);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO6);
/* Enable Voltage measurement */
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);

/* configure switches for digital I/O */
gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9);
gpio_set(GPIOC,
GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 |
GPIO5 | GPIO6 | GPIO7 | GPIO8 | GPIO9);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO8);
gpio_set(GPIOA, GPIO8);
}

s32 CHAN_ReadRawInput(int channel)
{
s32 value = 0;
switch(channel) {
case INP_AILERON: value = adc_array_raw[0]; break; // bug fix: right vertical
case INP_ELEVATOR: value = adc_array_raw[1]; break; // bug fix: right horizon
case INP_THROTTLE: value = adc_array_raw[2]; break; // bug fix: left horizon
case INP_RUDDER: value = adc_array_raw[3]; break; // bug fix: left vertical
case INP_AUX4: value = adc_array_raw[4]; break;
case INP_AUX5: value = adc_array_raw[5]; break;
case INP_AUX6: value = adc_array_raw[6]; break;
case INP_AUX7: value = adc_array_raw[7]; break;
case INP_SWA0: value = gpio_get(GPIOC, GPIO0); break;
case INP_SWA1: value = ! gpio_get(GPIOC, GPIO0); break;
case INP_SWB0: value = gpio_get(GPIOC, GPIO1); break;
case INP_SWB1: value = ! gpio_get(GPIOC, GPIO1); break;
case INP_SWC0: value = ! gpio_get(GPIOC, GPIO2); break;
case INP_SWC1: value = (gpio_get(GPIOC, GPIO2) && gpio_get(GPIOC, GPIO3)); break;
case INP_SWC2: value = ! gpio_get(GPIOC, GPIO3); break;
case INP_SWD0: value = gpio_get(GPIOC, GPIO6); break;
case INP_SWD1: value = ! gpio_get(GPIOC, GPIO6); break;
case INP_SWE0: value = ! gpio_get(GPIOC, GPIO4); break;
case INP_SWE1: value = (gpio_get(GPIOC, GPIO4) && gpio_get(GPIOC, GPIO5)); break;
case INP_SWE2: value = ! gpio_get(GPIOC, GPIO5); break;
case INP_SWF0: value = gpio_get(GPIOC, GPIO7); break;
case INP_SWF1: value = ! gpio_get(GPIOC, GPIO7); break;
case INP_SWG0: value = ! gpio_get(GPIOC, GPIO8); break;
case INP_SWG1: value = (gpio_get(GPIOC, GPIO8) && gpio_get(GPIOC, GPIO9)); break;
case INP_SWG2: value = ! gpio_get(GPIOC, GPIO9); break;
case INP_SWH0: value = gpio_get(GPIOA, GPIO8); break;
case INP_SWH1: value = ! gpio_get(GPIOA, GPIO8); break;
}
return value;
}
s32 CHAN_ReadInput(int channel)
{
s32 value = CHAN_ReadRawInput(channel);
if(channel <= INP_HAS_CALIBRATION) {
s32 max = Transmitter.calibration[channel - 1].max;
s32 min = Transmitter.calibration[channel - 1].min;
s32 zero = Transmitter.calibration[channel - 1].zero;
if(! zero) {
//If this input doesn't have a zero, calculate from max/min
zero = ((u32)max + min) / 2;
}
// Derate min and max by 1% to ensure we can get all the way to 100%
max = (max - zero) * 99 / 100;
min = (min - zero) * 99 / 100;
if(value >= zero) {
value = (value - zero) * CHAN_MAX_VALUE / max;
} else {
value = (value - zero) * CHAN_MIN_VALUE / min;
}
//Bound output
if (value > CHAN_MAX_VALUE)
value = CHAN_MAX_VALUE;
if (value < CHAN_MIN_VALUE)
value = CHAN_MIN_VALUE;
} else {
value = value ? CHAN_MAX_VALUE : CHAN_MIN_VALUE;
}
if (channel == INP_AILERON || channel == INP_ELEVATOR ||
channel == INP_THROTTLE || channel == INP_RUDDER)
{
value = -value;
}
return value;
}
55 changes: 55 additions & 0 deletions src/target/qemu/lcd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
This project 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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/fsmc.h>
#include "common.h"
#include "lcd.h"

u8 screen_flip;
const struct lcdtype *disp_type;

void lcd_cmd(uint8_t addr, uint8_t data)
{
}

void lcd_set_pos(unsigned int x0, unsigned int y0)
{
}

void LCD_DrawPixel(unsigned int color)
{
}

void LCD_DrawPixelXY(unsigned int x, unsigned int y, unsigned int color)
{
}

void LCD_DrawStart(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, enum DrawDir dir)
{
}

void LCD_DrawStop(void)
{
}

void LCD_Sleep()
{
}

void LCD_Init()
{
}

Loading

0 comments on commit f4aa3bd

Please sign in to comment.