Remove stm32 arch (#3586)

* remove stm32 arch

* remove libopencm3 and luftboot

---------

Co-authored-by: Fabien-B <Fabien-B@github.com>
This commit is contained in:
Fabien-B
2026-02-10 23:02:53 +01:00
committed by GitHub
parent ea2f5e029e
commit d464df9ee4
62 changed files with 5 additions and 10397 deletions

6
.gitmodules vendored
View File

@@ -1,9 +1,3 @@
[submodule "sw/ext/libopencm3"]
path = sw/ext/libopencm3
url = https://github.com/libopencm3/libopencm3.git
[submodule "sw/ext/luftboot"]
path = sw/ext/luftboot
url = https://github.com/paparazzi/luftboot.git
[submodule "sw/ext/fatfs"]
path = sw/ext/fatfs
url = https://github.com/paparazzi/fatfs.git

View File

@@ -1,273 +0,0 @@
# Hey Emacs, this is a -*- makefile -*-
#
# Copyright (C) 2009 Antoine Drouin
#
# This file is part of paparazzi.
#
# paparazzi 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 2, or (at your option)
# any later version.
#
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
#
# This is the common Makefile for the stm32-target.
#
SRC_ARCH = arch/stm32
# Pretty Printer
# Call with "make Q=''" to get full command display
Q=@
#
# find compiler toolchain
#
include $(PAPARAZZI_SRC)/conf/Makefile.arm-embedded-toolchain
ifeq ($(ARCH_L),f4)
MCU = cortex-m4
else
MCU = cortex-m3
endif
OPT ?= s
# Slightly bigger .elf files but gains the ability to decode macros
DEBUG_FLAGS ?= -ggdb3
CSTANDARD ?= -std=gnu99
CXXSTANDARD ?= -std=c++0x
CINCS = $(INCLUDES) -I$(PAPARAZZI_SRC)/sw/include
# add syscalls and c++ new/delete operators
$(TARGET).srcs += c++.cpp pprz_syscalls.c
$(TARGET).CXXFLAGS += -fno-sized-deallocation
# input files
SRCS = $($(TARGET).srcs)
#ASRC =
# object files
COBJ = $(SRCS:%.c=$(OBJDIR)/%.o)
OBJS = $(COBJ:%.cpp=$(OBJDIR)/%.o)
AOBJ = $(ASRC:%.S=$(OBJDIR)/%.o)
# linker script :
# if LDSCRIPT is defined in the airframe use that independantly of TARGET
# if not, and a TARGET.LDSCRIPT is defined, use that
# if not, use the default STM32f103re_flash.ld
ifndef LDSCRIPT
ifndef $(TARGET).LDSCRIPT
$(warning Linker script for target "$(TARGET)" on board "$(BOARD)" not defined. Using stm32default.ld.)
LDSCRIPT = $(SRC_ARCH)/stm32default.ld
else
LDSCRIPT = $($(TARGET).LDSCRIPT)
$(info Using "$($(TARGET).LDSCRIPT)" as ldscript for target "$(TARGET)".)
endif
endif
ifeq ($(ARCH_L), )
FLOAT_ABI ?= -msoft-float
else ifeq ($(ARCH_L),f4)
ifndef HARD_FLOAT
FLOAT_ABI ?= -msoft-float
else
FLOAT_ABI ?= -mfloat-abi=softfp -mfpu=fpv4-sp-d16
endif
endif
ARCH_FLAGS ?= -mcpu=$(MCU) -mthumb
# flags for warnings (C and C++)
WARN_FLAGS += -Wall -Wextra -Wunused
#WARN_FLAGS += -Wcast-qual
WARN_FLAGS += -Wcast-align
WARN_FLAGS += -Wpointer-arith
WARN_FLAGS += -Wswitch-default
WARN_FLAGS += -Wredundant-decls -Wmissing-declarations
WARN_FLAGS += -Wshadow
# common flags
CFLAGS += -O$(OPT)
CFLAGS += $(DEBUG_FLAGS)
CFLAGS += $(FLOAT_ABI)
CFLAGS += $(ARCH_FLAGS)
CFLAGS += $(USER_CFLAGS)
CFLAGS += $(WARN_FLAGS)
CXXFLAGS += -O$(OPT)
CXXFLAGS += $(DEBUG_FLAGS)
CXXFLAGS += $(FLOAT_ABI)
CXXFLAGS += $(ARCH_FLAGS)
CXXFLAGS += $(USER_CFLAGS)
CXXFLAGS += $(WARN_FLAGS)
CXXFLAGS += $(CINCS)
CXXFLAGS += $($(TARGET).CFLAGS)
CXXFLAGS += $(BOARD_CFLAGS)
CFLAGS += -I. -I./$(ARCH) -I../ext/libopencm3/include $(INCLUDES)
CFLAGS += -D__thumb2__
CFLAGS += -Wl,--gc-sections
CFLAGS += -mfix-cortex-m3-ldrd
CFLAGS += $(CSTANDARD)
#CFLAGS += -malignment-traps
CFLAGS += -fno-common
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(notdir $(subst $(suffix $<),.lst,$<))
CFLAGS += -Wstrict-prototypes -Wmissing-prototypes
CFLAGS += -Wnested-externs
CFLAGS += $($(TARGET).CFLAGS)
CFLAGS += $(BOARD_CFLAGS)
#CFLAGS += -fno-diagnostics-show-caret
ifneq ($(ARCH_L), )
ifeq ($(ARCH_L),f4)
CFLAGS += -DSTM32F4
CXXFLAGS += -DSTM32F4
endif
else
CFLAGS += -DSTM32F1
CXXFLAGS += -DSTM32F1
endif
# with cortex-m3 and m4 unaligned data can still be read
CFLAGS += -DPPRZLINK_UNALIGNED_ACCESS=1
# C++ only flags
CXXFLAGS += $(CXXSTANDARD)
CXXFLAGS += -I. -I./$(ARCH) -I../ext/libopencm3/include $(INCLUDES)
CXXFLAGS += -pipe -fshow-column
CXXFLAGS += -ffunction-sections -fdata-sections
CXXFLAGS += $($(TARGET).CXXFLAGS)
AFLAGS = -ahls -mapcs-32
AFLAGS += -mcpu=$(MCU) -mthumb
AFLAGS += -x assembler-with-cpp -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst)
LDFLAGS += -L../ext/libopencm3/lib
LDFLAGS += -T$(LDSCRIPT) -nostartfiles -O$(OPT) -mthumb -mcpu=$(MCU)
LDFLAGS += $(BOARD_LDFLAGS)
ifeq ($(ARCH_L), )
LDFLAGS += -mfix-cortex-m3-ldrd -msoft-float
else ifeq ($(ARCH_L),f4)
ifndef HARD_FLOAT
LDFLAGS += -mfix-cortex-m3-ldrd -msoft-float
else
LDFLAGS += -lnosys -D__thumb2__\
-mfloat-abi=softfp -mfpu=fpv4-sp-d16
endif
endif
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(TARGET).map,--cref,--gc-sections
ifneq ($(ARCH_L), )
LDLIBS += -lopencm3_stm32$(ARCH_L)
else
LDLIBS += -lopencm3_stm32f1
endif
LDLIBS += -lc -lm -lgcc
CPFLAGS = -j .isr_vector -j .text -j .data
CPFLAGS_BIN = -Obinary
CPFLAGS_HEX = -Oihex
ODFLAGS = -S
# some common informative targets
include $(PAPARAZZI_SRC)/conf/Makefile.arm-embedded-common
# Default target.
all: printcommands sizebefore build sizeafter
# depend order only for parallel make
sizebefore: | printcommands
build: | printcommands sizebefore
sizeafter: | build
build: $(OBJDIR) elf bin hex
# lss sym
$(OBJDIR):
@echo CREATING object dir $(OBJDIR)
@test -d $(OBJDIR) || mkdir -p $(OBJDIR)
elf: $(OBJDIR)/$(TARGET).elf
bin: $(OBJDIR)/$(TARGET).bin
hex: $(OBJDIR)/$(TARGET).hex
lss: $(OBJDIR)/$(TARGET).lss
sym: $(OBJDIR)/$(TARGET).sym
%.bin: %.elf
@echo OBJCB $@
$(Q)$(CP) $(CPFLAGS) $(CPFLAGS_BIN) $< $@
%.hex: %.elf
@echo OBJCH $@
$(Q)$(CP) $(CPFLAGS) $(CPFLAGS_HEX) $< $@
# Create extended listing file from ELF output file.
# testing: option -C
%.lss: %.elf
@echo OBJD $@
$(Q)$(DMP) -h -S -C $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo NM $@
$(Q)$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(OBJDIR)/$(TARGET).elf
.PRECIOUS : $(OBJS) $(AOBJ)
%.elf: $(OBJS) $(AOBJ) | $(OBJDIR)
@echo LD $@
$(Q)$(LD) $(LDFLAGS) $($(TARGET).LDFLAGS) -o $@ $(OBJS) $(AOBJ) $(LDLIBS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c $(OBJDIR)/../Makefile.ac
@echo CC $@
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
$(Q)$(CC) -MMD -c $(CFLAGS) $< -o $@
# Compile: create object files from C++ source files
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/../Makefile.ac
@echo CXX $@
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
$(Q)$(CXX) -MMD -c $(CXXFLAGS) $< -o $@
# Assemble: create object files from assembler source files. ARM/Thumb
$(AOBJ) : $(OBJDIR)/%.o : %.S
@echo AS $@
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
$(Q)$(CC) -c $(AFLAGS) $< -o $@
# Load upload rules
include $(PAPARAZZI_SRC)/conf/Makefile.stm32-upload
# Listing of phony targets.
.PHONY : all build elf bin lss sym
#
# Dependencies
#
ifneq ($(MAKECMDGOALS),clean)
DEPS = $(addprefix $(OBJDIR)/,$($(TARGET).srcs:.c=.d))
DEPS += $(addprefix $(OBJDIR)/,$($(TARGET).srcs:.cpp=.d))
-include $(DEPS)
endif

View File

@@ -1,30 +0,0 @@
timer subsystem/type (config options)
--------------------------------------------
(advanced timers using RCC_APB1)
TIM1 adc (if USE_AD_TIM1)
radio_control/ppm (if USE_PPM_TIM1, PPM input on SERVO6 pin)
actuators/pwm (if PWM_USE_TIM1)
TIM8 radio_control/ppm (if USE_PPM_TIM8)
(non-advanced timers using RCC_APB2)
TIM2 adc (if USE_AD_TIM2, default)
radio_control/ppm (if USE_PPM_TIM2, PPM input on UART1_RX pin)
actuators/pwm (if PWM_USE_TIM2)
TIM3 actuators/pwm (if PWM_USE_TIM3, PWM1..4 on LisaM)
TIM4 adc (if USE_AD_TIM4)
actuators/pwm (PWM6..7 on LisaL)
(PWM7..8) (if USE_SERVOS_7AND8)
TIM5 actuators/pwm (PWM/Servos 5..6 on LisaM)
TIM6 radio_control/spektrum
TIM7 none
TIM9 actuators/pwm (if PWM_USE_TIM9)
TIM12 actuators/pwm (if PWM_USE_TIM12)

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2013 Gautier Hattenberger
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Apogee (STM32F405RGT6, 1024K flash, 192K RAM). */
/* Define memory regions. */
MEMORY
{
/* only 128K (SRAM1 and SRAM2) are accessible by all AHB masters. */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
/* Leaving 128k of space at the end of rom for persistent settings */
rom (rx) : ORIGIN = 0x08000000, LENGTH = 896K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,36 +0,0 @@
/*
* Hey Emacs, this is a -*- makefile -*-
*
* Copyright (C) 2012 Sergey Krukowski <softsr@yahoo.de>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Krooz (STM32F405, 1024K flash, 192K RAM). */
/* Define memory regions. */
MEMORY
{
/* Only 128K (SRAM1 and SRAM2) are accessible by all AHB masters. */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
/* Leaving 128k of space at the end of rom for persistent settings */
rom (rx) : ORIGIN = 0x08004000, LENGTH = 896K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,6 +0,0 @@
#include "led.h"
#ifdef LED_STP08
uint8_t led_status[NB_LED];
#endif

View File

@@ -1,108 +0,0 @@
/*
* Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef LED_HW_H
#define LED_HW_H
#include "mcu_periph/gpio.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include BOARD_CONFIG
#include "std.h"
/*
*
* Regular GPIO driven LEDs
*
*/
#ifndef LED_STP08
#define _LED_EVAL(i) i
#define LED_GPIO(i) _LED_EVAL(LED_ ## i ## _GPIO)
#define LED_GPIO_PIN(i) _LED_EVAL(LED_ ## i ## _GPIO_PIN)
#define LED_GPIO_ON(i) _LED_EVAL(LED_ ## i ## _GPIO_ON)
#define LED_GPIO_OFF(i) _LED_EVAL(LED_ ## i ## _GPIO_OFF)
#define LED_AFIO_REMAP(i) _LED_EVAL(LED_ ## i ## _AFIO_REMAP)
#define LED_INIT(i) { \
gpio_setup_output(LED_GPIO(i), LED_GPIO_PIN(i)); \
LED_AFIO_REMAP(i); \
}
#define LED_ON(i) LED_GPIO_ON(i)(LED_GPIO(i), LED_GPIO_PIN(i))
#define LED_OFF(i) LED_GPIO_OFF(i)(LED_GPIO(i), LED_GPIO_PIN(i))
#define LED_TOGGLE(i) gpio_toggle(LED_GPIO(i), LED_GPIO_PIN(i))
#define LED_DISABLE(i) gpio_setup_input(LED_GPIO(i), LED_GPIO_PIN(i))
#define LED_PERIODIC() {}
/*
*
* Shift register driven LEDs
*
*/
#else /* LED_STP08 */
#define NB_LED 8
extern uint8_t led_status[NB_LED];
/* Lisa/L uses a shift register for driving LEDs */
/* PA8 led_clk */
/* PC15 led_data */
#define LED_INIT(_i) { \
rcc_periph_clock_enable(RCC_GPIOA); \
rcc_periph_clock_enable(RCC_GPIOC); \
gpio_set_mode(GPIOA, \
GPIO_MODE_OUTPUT_50_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, \
GPIO8); \
gpio_set_mode(GPIOC, \
GPIO_MODE_OUTPUT_50_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, \
GPIO15); \
for(uint8_t _cnt=0; _cnt<NB_LED; _cnt++) \
led_status[_cnt] = false; \
}
#define LED_ON(i) { led_status[i] = true; }
#define LED_OFF(i) { led_status[i] = false; }
#define LED_TOGGLE(i) {led_status[i] = !led_status[i];}
#define LED_DISABLE(i) LED_OFF(i)
#define LED_PERIODIC() { \
for (uint8_t _cnt = 0; _cnt < NB_LED; _cnt++) { \
if (led_status[_cnt]) \
gpio_set(GPIOC, GPIO15); \
else \
gpio_clear(GPIOC, GPIO15); \
gpio_set(GPIOA, GPIO8); /* clock rising edge */ \
gpio_clear(GPIOA, GPIO8); /* clock falling edge */ \
} \
}
#endif /* LED_STP08 */
#endif /* LED_HW_H */

View File

@@ -1,35 +0,0 @@
/*
* Hey Emacs, this is a -*- makefile -*-
*
* Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Lisa-L (STM32F103RET6, 512K flash, 64K RAM). */
/* Define memory regions. */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
/* Leaving 2k of space at the end of rom for stored settings */
rom (rx) : ORIGIN = 0x08000000, LENGTH = 510K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,35 +0,0 @@
/*
* Hey Emacs, this is a -*- makefile -*-
*
* Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Lisa-M (STM32F105RCT6, 256K flash, 64K RAM). */
/* Define memory regions. */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
/* Leaving 2k of space at the end of rom for stored settings */
rom (rx) : ORIGIN = 0x08000000, LENGTH = 254K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,35 +0,0 @@
/*
* Hey Emacs, this is a -*- makefile -*-
*
* Copyright (C) 2012 Sergey Krukowski <softsr@yahoo.de>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Lisa/MX (STM32F415, 1024K flash, 192K RAM). */
/* Define memory regions. */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
/* Reserving 128kb flash for persistent settings. */
rom (rx) : ORIGIN = 0x08000000, LENGTH = 896K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,362 +0,0 @@
/*
* Copyright (C) 2010-2012 The Paparazzi team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_arch.c
* @brief stm32 arch dependant microcontroller initialisation functions.
* @ingroup stm32_arch
*/
#include "mcu.h"
#include BOARD_CONFIG
#include <inttypes.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/flash.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/stm32/rtc.h>
#include <libopencm3/stm32/pwr.h>
#include "std.h"
#if defined(STM32F4)
/* untested, should go into libopencm3 */
const struct rcc_clock_scale rcc_hse_24mhz_3v3[RCC_CLOCK_3V3_END] = {
{ /* 48MHz */
.pllm = 24,
.plln = 96,
.pllp = 2,
.pllq = 2,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 48000000,
.apb1_frequency = 12000000,
.apb2_frequency = 24000000,
},
{ /* 84MHz */
.pllm = 24,
.plln = 336,
.pllp = 4,
.pllq = 7,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2,
.ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_2WS,
.ahb_frequency = 84000000,
.apb1_frequency = 42000000,
.apb2_frequency = 84000000,
},
{ /* 120MHz */
.pllm = 24,
.plln = 240,
.pllp = 2,
.pllq = 5,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 120000000,
.apb1_frequency = 30000000,
.apb2_frequency = 60000000,
},
{ /* 168MHz */
.pllm = 24,
.plln = 336,
.pllp = 2,
.pllq = 7,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS,
.ahb_frequency = 168000000,
.apb1_frequency = 42000000,
.apb2_frequency = 84000000,
},
};
#endif
#if defined(STM32F1)
/*---------------------------------------------------------------------------*/
/** @brief RCC Set System Clock HSE at 24MHz from HSE at 24MHz
*/
void rcc_clock_setup_in_hse_24mhz_out_24mhz_pprz(void);
void rcc_clock_setup_in_hse_24mhz_out_24mhz_pprz(void)
{
/* Enable internal high-speed oscillator. */
rcc_osc_on(RCC_HSI);
rcc_wait_for_osc_ready(RCC_HSI);
/* Select HSI as SYSCLK source. */
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK);
/* Enable external high-speed oscillator 24MHz. */
rcc_osc_on(RCC_HSE);
rcc_wait_for_osc_ready(RCC_HSE);
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);
/*
* Set prescalers for AHB, ADC, ABP1, ABP2.
* Do this before touching the PLL (TODO: why?).
*/
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 72MHz */
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 14MHz */
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 36MHz */
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 72MHz */
/*
* Sysclk runs with 24MHz -> 0 waitstates.
* 0WS from 0-24MHz
* 1WS from 24-48MHz
* 2WS from 48-72MHz
*/
flash_set_ws(FLASH_ACR_LATENCY_0WS);
/*
* Set the PLL multiplication factor to 2.
* 24MHz (external) * 2 (multiplier) / 2 (RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2) = 24MHz
*/
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL2);
/* Select HSE as PLL source. */
rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK);
/*
* External frequency divide by 2 before entering PLL
* (only valid/needed for HSE).
*/
rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2);
rcc_osc_on(RCC_PLL);
rcc_wait_for_osc_ready(RCC_PLL);
/* Select PLL as SYSCLK source. */
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
/* Set the peripheral clock frequencies used */
rcc_ahb_frequency = 24000000;
rcc_apb1_frequency = 24000000;
rcc_apb2_frequency = 24000000;
}
#endif
#ifdef SYSTEM_MEMORY_BASE
void reset_to_dfu(void) {
// Request DFU at boot (init_dfu)
pwr_disable_backup_domain_write_protect();
RTC_BKPXR(0) = 0xFF;
pwr_enable_backup_domain_write_protect();
// Reset
scb_reset_system();
}
typedef void resetHandler_t(void);
typedef struct isrVector_s {
volatile uint32_t stackEnd;
resetHandler_t *resetHandler;
} isrVector_t;
static isrVector_t *system_isr_vector_table_base = (isrVector_t *) SYSTEM_MEMORY_BASE; // Find in ST AN2606. Defined in board header.
static void init_dfu(void) {
/* Reset to DFU if requested */
rcc_periph_clock_enable(RCC_RTC);
rcc_periph_clock_enable(RCC_PWR);
if (RTC_BKPXR(0) == 0xFF) {
// DFU request
// 0. Reset request
pwr_disable_backup_domain_write_protect();
RTC_BKPXR(0) = 0x00;
pwr_enable_backup_domain_write_protect();
// 1. Set MSP to system_isr_vector_table_base.stackEnd
// (betaflight system_stm32f4xx.c::75)
// (betaflight cmsis_armcc.h::226
register uint32_t __regMainStackPointer __asm("msp") __attribute__((unused)); // Note: declared unused to suppress gcc warning, not actually unused!
__regMainStackPointer = system_isr_vector_table_base->stackEnd; // = topOfMainStack;
// 2. system_isr_vector_table_base.resetHandler() (betaflight system_stm32f4xx.c::76)
system_isr_vector_table_base->resetHandler();
while (1);
}
}
#endif // SYSTEM_MEMORY_BASE
void mcu_arch_init(void)
{
#ifdef SYSTEM_MEMORY_BASE
init_dfu();
#endif
#if LUFTBOOT
PRINT_CONFIG_MSG("We are running luftboot, the interrupt vector is being relocated.")
#if defined STM32F4
SCB_VTOR = 0x00004000;
#else
SCB_VTOR = 0x00002000;
#endif
#endif
#if EXT_CLK == 8000000
#if defined(STM32F1)
PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 72MHz.")
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);
#elif defined(STM32F4)
#if AHB_CLK == 84000000
PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 84MHz.")
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_84MHZ]);
#else
PRINT_CONFIG_MSG("Using 8MHz external clock to PLL it to 168MHz.")
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#endif
#endif
#elif EXT_CLK == 12000000
#if defined(STM32F1)
PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 72MHz.")
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE12_72MHZ]);
#elif defined(STM32F4)
PRINT_CONFIG_MSG("Using 12MHz external clock to PLL it to 168MHz.")
rcc_clock_setup_pll(&rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#endif
#elif EXT_CLK == 16000000
#if defined(STM32F4)
PRINT_CONFIG_MSG("Using 16MHz external clock to PLL it to 168MHz.")
rcc_clock_setup_pll(&rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#endif
#elif EXT_CLK == 24000000
#if defined(STM32F4)
PRINT_CONFIG_MSG("Using 24MHz external clock to PLL it to 168MHz.")
rcc_clock_setup_pll(&rcc_hse_24mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#elif defined(STM32F1)
rcc_clock_setup_in_hse_24mhz_out_24mhz_pprz();
#endif
#elif EXT_CLK == 25000000
#if defined(STM32F4)
PRINT_CONFIG_MSG("Using 25MHz external clock to PLL it to 168MHz.")
rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#endif
#else
#error EXT_CLK is either set to an unsupported frequency or not defined at all. Please check!
#endif
/* Configure priority grouping 0 bits for pre-emption priority and 4 bits for sub-priority.
* this was previously in i2c driver
* FIXME is it really needed ?
*/
scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_NOGROUP_SUB16);
}
#if defined(STM32F1)
#define RCC_CFGR_PPRE2_SHIFT 11
#define RCC_CFGR_PPRE2 (7 << RCC_CFGR_PPRE2_SHIFT)
#define RCC_CFGR_PPRE1_SHIFT 8
#define RCC_CFGR_PPRE1 (7 << RCC_CFGR_PPRE1_SHIFT)
static inline uint32_t rcc_get_ppre1(void)
{
return RCC_CFGR & RCC_CFGR_PPRE1;
}
static inline uint32_t rcc_get_ppre2(void)
{
return RCC_CFGR & RCC_CFGR_PPRE2;
}
#elif defined(STM32F4)
static inline uint32_t rcc_get_ppre1(void)
{
return RCC_CFGR & ((1 << 10) | (1 << 11) | (1 << 12));
}
static inline uint32_t rcc_get_ppre2(void)
{
return RCC_CFGR & ((1 << 13) | (1 << 14) | (1 << 15));
}
#endif
/** @brief Get Timer clock frequency (before prescaling)
* Only valid if using the internal clock for the timer.
* Currently implemented for STM32F1x and STM32F405xx/407xx STM32F415xx/417xx.
* Not valid for STM32F42xxx and STM32F43xxx.
* @param[in] timer_peripheral Unsigned int32. Timer register address base
* @return Unsigned int32. Timer base frequency
*/
uint32_t timer_get_frequency(uint32_t timer_peripheral)
{
switch (timer_peripheral) {
// Timers on high speed APB2
case TIM1:
case TIM8:
#ifdef TIM9
case TIM9:
#endif
#ifdef TIM10
case TIM10:
#endif
#ifdef TIM11
case TIM11:
#endif
if (!rcc_get_ppre2()) {
/* without APB2 prescaler, runs at APB2 freq */
return rcc_apb2_frequency;
} else {
/* with any ABP2 prescaler, runs at 2 * APB2 freq */
return rcc_apb2_frequency * 2;
}
// timers on low speed APB1
case TIM2:
case TIM3:
case TIM4:
case TIM5:
case TIM6:
case TIM7:
#ifdef TIM12
case TIM12:
#endif
#ifdef TIM13
case TIM13:
#endif
#ifdef TIM14
case TIM14:
#endif
if (!rcc_get_ppre1()) {
/* without APB1 prescaler, runs at APB1 freq */
return rcc_apb1_frequency;
} else {
/* with any ABP1 prescaler, runs at 2 * APB1 freq */
return rcc_apb1_frequency * 2;
}
default:
// other timers currently not supported
break;
}
return 0;
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2010-2012 The Paparazzi team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_arch.h
* @brief stm32 arch dependant microcontroller initialisation functions.
* @addtogroup stm32_arch STM32 architecture
*/
#ifndef STM32_MCU_ARCH_H
#define STM32_MCU_ARCH_H
#include "std.h"
#include BOARD_CONFIG
extern void mcu_arch_init(void);
#ifdef SYSTEM_MEMORY_BASE
extern void reset_to_dfu(void);
#endif
/* should probably not be here
* a couple of macros to use the rev instruction
*/
#define MyByteSwap16(in, out) { \
asm volatile ( \
"rev16 %0, %1\n\t" \
: "=r" (out) \
: "r"(in) \
); \
}
uint32_t timer_get_frequency(uint32_t timer_peripheral);
#endif /* STM32_MCU_ARCH_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) 2010-2012 Paparazzi team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_periph/adc_arch.h
* @ingroup stm32_arch
*
* Driver for the analog to digital converters on STM32.
*/
#ifndef ADC_ARCH_H
#define ADC_ARCH_H
#include BOARD_CONFIG
/* Set the correct ADC resolution */
#ifndef ADC_RESOLUTION
#define ADC_RESOLUTION 4096
#endif
enum adc1_channels {
#ifdef AD1_1_CHANNEL
AD1_1,
#endif
#ifdef AD1_2_CHANNEL
AD1_2,
#endif
#ifdef AD1_3_CHANNEL
AD1_3,
#endif
#ifdef AD1_4_CHANNEL
AD1_4,
#endif
ADC1_END
};
enum adc2_channels {
ADC2_BEGIN = ADC1_END-1,
#ifdef AD2_1_CHANNEL
AD2_1,
#endif
#ifdef AD2_2_CHANNEL
AD2_2,
#endif
#ifdef AD2_3_CHANNEL
AD2_3,
#endif
#ifdef AD2_4_CHANNEL
AD2_4,
#endif
ADC2_END
};
enum adc3_channels {
ADC3_BEGIN = ADC2_END-1,
#ifdef AD3_1_CHANNEL
AD3_1,
#endif
#ifdef AD3_2_CHANNEL
AD3_2,
#endif
#ifdef AD3_3_CHANNEL
AD3_3,
#endif
#ifdef AD3_4_CHANNEL
AD3_4,
#endif
ADC3_END
};
#if USE_ADC_WATCHDOG
/* Watchdog callback type definition
*/
typedef void (*adc_watchdog_callback)(void);
/* Watchdog register function
*
* @param adc adc bank to monitor
* @param chan adc channel to monitor
* @param low low threshhold for callback trigger
* @param high high threshhold for callback trigger
*/
extern void register_adc_watchdog(uint32_t adc, uint8_t chan, uint16_t low, uint16_t high, adc_watchdog_callback cb);
#endif
#endif /* ADC_ARCH_H */

View File

@@ -1,259 +0,0 @@
/*
* Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_periph/can_arch.c
* @ingroup stm32_arch
*
* Handling of CAN hardware for STM32.
*/
#include <stdint.h>
#include <string.h>
#include "mcu_periph/can_arch.h"
#include "mcu_periph/can.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/can.h>
#include <libopencm3/cm3/nvic.h>
#include "led.h"
#ifdef RTOS_PRIO
#define NVIC_USB_LP_CAN_RX0_IRQ_PRIO RTOS_PRIO+1
#else
#define NVIC_USB_LP_CAN_RX0_IRQ_PRIO 1
#define NVIC_CAN1_RX_IRQ_PRIO 1
#endif
void _can_run_rx_callback(uint32_t id, uint8_t *buf, uint8_t len);
struct can_arch_periph {
uint32_t canport;
bool can_initialized;
struct pprzcan_frame rxframe;
bool new_rxframe;
struct pprzaddr_can addr;
};
struct can_arch_periph can1_arch_s = {
.canport = CAN1,
.can_initialized = false,
.addr = {.can_ifindex = 1},
.rxframe = {0},
.new_rxframe = false;
};
void can_hw_init(void)
{
can1.arch_struct = &can1_arch_s;
#ifdef STM32F1
/* Enable peripheral clocks. */
rcc_periph_clock_enable(RCC_AFIO);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_CAN1);
/* Remap the gpio pin if necessary. */
AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB;
/* Configure CAN pin: RX (input pull-up). */
gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX);
gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX);
/* Configure CAN pin: TX (output push-pull). */
gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX);
/* NVIC setup. */
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, NVIC_USB_LP_CAN_RX0_IRQ_PRIO);
#elif STM32F4
/* Enable peripheral clocks. */
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_CAN1);
/* set up pins for CAN1TX & CAN1RX alternate function */
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);
gpio_set_af(GPIOB, GPIO_AF9, GPIO8 | GPIO9);
/* enable interrupts on RX0 FIFO */
nvic_enable_irq(NVIC_CAN1_RX0_IRQ);
nvic_set_priority(NVIC_CAN1_RX0_IRQ, NVIC_CAN1_RX_IRQ_PRIO);
#endif
/* Reset CAN. */
can_reset(can1_arch_s.canport);
/* CAN cell init.
* For time quanta calculation see STM32 reference manual
* section 24.7.7 "Bit timing" page 645
*
* To talk to CSC using LPC mcu we need a baud rate of 375kHz
* The APB1 runs at 36MHz therefor we select a prescaler of 12
* resulting in time quanta frequency of 36MHz / 12 = 3MHz
*
* As the Bit time is combined of 1tq for SYNC_SEG, TS1tq for bit
* segment 1 and TS2tq for bit segment 2:
* BITtq = 1tq + TS1tq + TS2tq
*
* We can choose to use TS1 = 3 and TS2 = 4 getting
* 1tq + 3tq + 4tq = 8tq per bit therefor a bit frequency is
* 3MHZ / 8 = 375kHz
*
* Maximum baud rate of CAN is 1MHz so we can choose to use
* prescaler of 2 resulting in a quanta frequency of 36MHz / 2 = 18Mhz
*
* So we need to devide the frequency by 18. This can be accomplished
* using TS1 = 10 and TS2 = 7 resulting in:
* 1tq + 10tq + 7tq = 18tq
*
* NOTE: Although it is out of spec I managed to have CAN run at 2MBit
* Just decrease the prescaler to 1. It worked for me(tm) (esden)
*/
if (can_init(can1_arch_s.canport,
false, /* TTCM: Time triggered comm mode? */
true, /* ABOM: Automatic bus-off management? */
false, /* AWUM: Automatic wakeup mode? */
false, /* NART: No automatic retransmission? */
false, /* RFLM: Receive FIFO locked mode? */
false, /* TXFP: Transmit FIFO priority? */
#ifdef STM32F1
CAN_BTR_SJW_1TQ,
CAN_BTR_TS1_10TQ,
CAN_BTR_TS2_7TQ,
#elif STM32F4
CAN_BTR_SJW_1TQ,
CAN_BTR_TS1_14TQ,
CAN_BTR_TS2_6TQ,
#endif
2, /* BRP+1: Baud rate prescaler */
false, /* loopback mode */
false)) { /* silent mode */
/* TODO we need something somewhere where we can leave a note
* that CAN was unable to initialize. Just like any other
* driver should...
*/
can_reset(can1_arch_s.canport);
return;
}
/* CAN filter 0 init. */
can_filter_id_mask_32bit_init(0, /* Filter ID */
0, /* CAN ID */
0, /* CAN ID mask */
0, /* FIFO assignment (here: FIFO0) */
true); /* Enable the filter. */
/* Enable CAN RX interrupt. */
can_enable_irq(can1_arch_s.canport, CAN_IER_FMPIE0);
/* Remember that we succeeded to initialize. */
can1_arch_s.can_initialized = true;
}
int can_transmit_frame(struct pprzcan_frame* txframe, struct pprzaddr_can* addr) {
if (!can1_arch_s.can_initialized) {
return -2;
}
if(txframe->len > 8) {
return -1; //does not currently support CANFD
}
return can_transmit(can1_arch_s.canport,
#ifdef USE_CAN_EXT_ID
txframe->can_id & CAN_EID_MASK,
true, /* IDE: CAN ID extended */
#else
txframe->can_id & CAN_SID_MASK,
false, /* IDE: CAN ID standard */
#endif
txframe->can_id & CAN_FRAME_RTR, /* RTR: Request transmit? */
can_len_to_dlc(txframe->len), /* DLC: Data length */
(uint8_t *)txframe->data);
}
#ifdef STM32F1
void usb_lp_can_rx0_isr(void)
#elif STM32F4
void can1_rx0_isr(void)
#else
#error "CAN unsuported on this MCU!"
void __unsupported_isr(void)
#endif
{
uint32_t id;
uint8_t fmi;
bool ext, rtr;
uint8_t dlc;
struct pprzcan_frame* rxframe = &can1_arch_s.rxframe;
can_receive(can1_arch_s.canport,
0, /* FIFO: 0 */
false, /* Release */
&rxframe->can_id,
&ext,
&rtr,
&fmi,
&dlc,
rxframe->data,
&rxframe->timestamp);
rxframe->len = can_dlc_to_len(dlc);
if(ext) {
rxframe->can_id |= CAN_FRAME_EFF;
}
if(rtr) {
rxframe->can_id |= CAN_FRAME_RTR;
}
can1_arch_s.new_rxframe = true;
can_fifo_release(can1_arch_s.canport, 0);
}
void can_event() {
if(can1_arch_s.new_rxframe) {
for(int i=0; i<CAN_NB_CALLBACKS_MAX; i++) {
if(can1.callbacks[i] != NULL) {
can1.callbacks[i](&can1_arch_s.rxframe, &can1_arch_s.addr, can1.callback_user_data[i]);
}
}
can1_arch_s.new_rxframe = false;
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_periph/can_arch.h
* @ingroup stm32_arch
*
* Handling of CAN hardware for STM32.
*/
#ifndef MCU_PERIPH_STM32_CAN_ARCH_H
#define MCU_PERIPH_STM32_CAN_ARCH_H
void can_hw_init(void);
void can_event(void);
#if defined STM32F1
void usb_lp_can1_rx0_irq_handler(void);
#endif
#endif /* MCU_PERIPH_STM32_CAN_ARCH_H */

View File

@@ -1,167 +0,0 @@
/*
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/gpio_arch.c
* @ingroup stm32_arch
*
* GPIO helper functions for STM32F1 and STM32F4.
*/
#include "mcu_periph/gpio.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
void gpio_enable_clock(uint32_t port)
{
switch (port) {
case GPIOA:
rcc_periph_clock_enable(RCC_GPIOA);
break;
case GPIOB:
rcc_periph_clock_enable(RCC_GPIOB);
break;
case GPIOC:
rcc_periph_clock_enable(RCC_GPIOC);
break;
case GPIOD:
rcc_periph_clock_enable(RCC_GPIOD);
break;
#ifdef GPIOE
case GPIOE:
rcc_periph_clock_enable(RCC_GPIOE);
break;
#endif
#ifdef GPIOF
case GPIOF:
rcc_periph_clock_enable(RCC_GPIOF);
break;
#endif
#ifdef GPIOG
case GPIOG:
rcc_periph_clock_enable(RCC_GPIOG);
break;
#endif
#ifdef GPIOH
case GPIOH:
rcc_periph_clock_enable(RCC_GPIOH);
break;
#endif
#ifdef GPIOI
case GPIOI:
rcc_periph_clock_enable(RCC_GPIOI);
break;
#endif
default:
break;
};
}
#ifdef STM32F1
void gpio_setup_output(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_set_mode(port, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, gpios);
}
void gpio_setup_input(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_set_mode(port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, gpios);
}
void gpio_setup_input_pullup(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_set(port, gpios);
gpio_set_mode(port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, gpios);
}
void gpio_setup_input_pulldown(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_clear(port, gpios);
gpio_set_mode(port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, gpios);
}
void gpio_setup_pin_af(uint32_t port, uint16_t pin, uint32_t af, bool is_output)
{
gpio_enable_clock(port);
/* remap alternate function if needed */
if (af) {
rcc_periph_clock_enable(RCC_AFIO);
AFIO_MAPR |= af;
}
if (is_output) {
gpio_set_mode(port, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, pin);
} else {
gpio_set_mode(port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, pin);
}
}
void gpio_setup_pin_analog(uint32_t port, uint16_t pin)
{
gpio_enable_clock(port);
gpio_set_mode(port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, pin);
}
#elif defined STM32F4
void gpio_setup_output(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_mode_setup(port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, gpios);
}
void gpio_setup_input(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_mode_setup(port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, gpios);
}
void gpio_setup_input_pullup(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_mode_setup(port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, gpios);
}
void gpio_setup_input_pulldown(uint32_t port, uint16_t gpios)
{
gpio_enable_clock(port);
gpio_mode_setup(port, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, gpios);
}
void gpio_setup_pin_af(uint32_t port, uint16_t pin, uint8_t af, bool is_output __attribute__((unused)))
{
gpio_enable_clock(port);
gpio_set_af(port, af, pin);
gpio_mode_setup(port, GPIO_MODE_AF, GPIO_PUPD_NONE, pin);
}
void gpio_setup_pin_analog(uint32_t port, uint16_t pin)
{
gpio_enable_clock(port);
gpio_mode_setup(port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, pin);
}
#endif

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/gpio_arch.h
* @ingroup stm32_arch
*
* GPIO helper functions for STM32F1 and STM32F4.
*
* The gpio_set and gpio_clear functions are already available from libopencm3.
*/
#ifndef GPIO_ARCH_H
#define GPIO_ARCH_H
#include <libopencm3/stm32/gpio.h>
/**
* Abstract gpio port type for hardware independent part
*/
typedef uint32_t gpio_port_t;
/**
* Setup one or more pins of the given GPIO port as outputs.
* @param[in] port
* @param[in] gpios If multiple pins are to be changed, use logical OR '|' to separate them.
*/
extern void gpio_setup_output(uint32_t port, uint16_t gpios);
/**
* Setup one or more pins of the given GPIO port as inputs.
* @param[in] port
* @param[in] gpios If multiple pins are to be changed, use logical OR '|' to separate them.
*/
extern void gpio_setup_input(uint32_t port, uint16_t gpios);
/**
* Setup one or more pins of the given GPIO port as inputs with pull up resistor enabled.
* @param[in] port
* @param[in] gpios If multiple pins are to be changed, use logical OR '|' to separate them.
*/
extern void gpio_setup_input_pullup(uint32_t port, uint16_t gpios);
/**
* Setup one or more pins of the given GPIO port as inputs with pull down resistors enabled.
* @param[in] port
* @param[in] gpios If multiple pins are to be changed, use logical OR '|' to separate them.
*/
extern void gpio_setup_input_pulldown(uint32_t port, uint16_t gpios);
/**
* Setup a gpio for input or output with alternate function.
* This is an STM32 specific helper funtion and should only be used in stm32 arch code.
*/
#if defined(STM32F1)
extern void gpio_setup_pin_af(uint32_t port, uint16_t pin, uint32_t af, bool is_output);
#else
extern void gpio_setup_pin_af(uint32_t port, uint16_t pin, uint8_t af, bool is_output);
#endif
/**
* Setup a gpio for analog use.
* This is an STM32 specific helper funtion and should only be used in stm32 arch code.
*/
extern void gpio_setup_pin_analog(uint32_t port, uint16_t pin);
/**
* Enable the relevant clock.
* This is an STM32 specific helper funtion and should only be used in stm32 arch code.
*/
extern void gpio_enable_clock(uint32_t port);
#endif /* GPIO_ARCH_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
/*
* Copyright (C) 2009-2012 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/i2c_arch.h
* @ingroup stm32_arch
*
* Hardware level I2C handling for the STM32.
*/
#ifndef I2C_HW_H
#define I2C_HW_H
#include <libopencm3/stm32/i2c.h>
#if USE_I2C1
extern void i2c1_hw_init(void);
extern void i2c1_ev_irq_handler(void);
extern void i2c1_er_irq_handler(void);
#endif /* USE_I2C1 */
#if USE_I2C2
extern void i2c2_hw_init(void);
extern void i2c2_ev_irq_handler(void);
extern void i2c2_er_irq_handler(void);
#endif /* USE_I2C2 */
#if USE_I2C3 && defined STM32F4
extern void i2c3_hw_init(void);
extern void i2c3_ev_irq_handler(void);
extern void i2c3_er_irq_handler(void);
#endif /* USE_I2C3 */
#endif /* I2C_HW_H */

View File

@@ -1,354 +0,0 @@
/*
* Copyright (C) 2014 Gautier Hattenberger
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/pwm_input_arch.c
* @ingroup stm32_arch
*
* handling of smt32 PWM input using a timer with capture.
*/
#include "mcu_periph/pwm_input.h"
#include BOARD_CONFIG
#include "generated/airframe.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_periph/sys_time.h"
#include "mcu_periph/gpio.h"
// for timer_get_frequency
#include "mcu_arch.h"
#define ONE_MHZ_CLK 1000000
#ifdef NVIC_TIM_IRQ_PRIO
#define PWM_INPUT_IRQ_PRIO NVIC_TIM_IRQ_PRIO
#else
#define PWM_INPUT_IRQ_PRIO 2
#endif
static inline void pwm_input_set_timer(uint32_t tim, uint32_t ticks_per_usec)
{
timer_set_mode(tim, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_period(tim, 0xFFFF);
uint32_t timer_clk = timer_get_frequency(tim);
timer_set_prescaler(tim, (timer_clk / (ticks_per_usec * ONE_MHZ_CLK)) - 1);
timer_enable_counter(tim);
}
void pwm_input_init(void)
{
int i;
// initialize the arrays to 0
for (i = 0; i < PWM_INPUT_NB; i++) {
pwm_input_duty_tics[i] = 0;
pwm_input_duty_valid[i] = 0;
pwm_input_period_tics[i] = 0;
pwm_input_period_valid[i] = 0;
}
/** Configure timers
* - timer clock enable
* - base configuration
* - enable counter
*/
#if USE_PWM_INPUT_TIM1
rcc_periph_clock_enable(RCC_TIM1);
rcc_periph_reset_pulse(RST_TIM1);
pwm_input_set_timer(TIM1, TIM1_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM2
rcc_periph_clock_enable(RCC_TIM2);
rcc_periph_reset_pulse(RST_TIM2);
pwm_input_set_timer(TIM2, TIM2_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM3
rcc_periph_clock_enable(RCC_TIM3);
rcc_periph_reset_pulse(RST_TIM3);
pwm_input_set_timer(TIM3, TIM3_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM4
rcc_periph_clock_enable(RCC_TIM4);
rcc_periph_reset_pulse(RST_TIM4);
pwm_input_set_timer(TIM4, TIM4_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM5
rcc_periph_clock_enable(RCC_TIM5);
rcc_periph_reset_pulse(RST_TIM5);
pwm_input_set_timer(TIM5, TIM5_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM8
rcc_periph_clock_enable(RCC_TIM8);
rcc_periph_reset_pulse(RST_TIM8);
pwm_input_set_timer(TIM8, TIM8_TICKS_PER_USEC);
#endif
#if USE_PWM_INPUT_TIM9
rcc_periph_clock_enable(RCC_TIM9);
rcc_periph_reset_pulse(RST_TIM9);
pwm_input_set_timer(TIM9, TIM9_TICKS_PER_USEC);
#endif
#ifdef USE_PWM_INPUT1
/* GPIO configuration as input capture for timer */
gpio_setup_pin_af(PWM_INPUT1_GPIO_PORT, PWM_INPUT1_GPIO_PIN, PWM_INPUT1_GPIO_AF, FALSE);
/** TIM configuration: Input Capture mode
* Two IC signals are mapped to the same TI input
*/
timer_ic_set_input(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_PERIOD, PWM_INPUT1_TIMER_INPUT);
timer_ic_set_input(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_DUTY, PWM_INPUT1_TIMER_INPUT);
#if USE_PWM_INPUT1 == PWM_PULSE_TYPE_ACTIVE_LOW
timer_ic_set_polarity(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_PERIOD, TIM_IC_RISING);
timer_ic_set_polarity(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_DUTY, TIM_IC_FALLING);
#elif USE_PWM_INPUT1 == PWM_PULSE_TYPE_ACTIVE_HIGH
timer_ic_set_polarity(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_PERIOD, TIM_IC_FALLING);
timer_ic_set_polarity(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_DUTY, TIM_IC_RISING);
#endif
/* Select the valid trigger input */
timer_slave_set_trigger(PWM_INPUT1_TIMER, PWM_INPUT1_SLAVE_TRIG);
/* Configure the slave mode controller in reset mode */
timer_slave_set_mode(PWM_INPUT1_TIMER, TIM_SMCR_SMS_RM);
/* Enable timer Interrupt(s). */
nvic_set_priority(PWM_INPUT1_IRQ, PWM_INPUT_IRQ_PRIO);
nvic_enable_irq(PWM_INPUT1_IRQ);
#ifdef PWM_INPUT1_IRQ2
nvic_set_priority(PWM_INPUT1_IRQ2, PWM_INPUT_IRQ_PRIO);
nvic_enable_irq(PWM_INPUT1_IRQ2);
#endif
/* Enable the Capture/Compare and Update interrupt requests. */
timer_enable_irq(PWM_INPUT1_TIMER, (PWM_INPUT1_CC_IE | TIM_DIER_UIE));
/* Enable capture channel. */
timer_ic_enable(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_PERIOD);
timer_ic_enable(PWM_INPUT1_TIMER, PWM_INPUT1_CHANNEL_DUTY);
#endif
#ifdef USE_PWM_INPUT2
/* GPIO configuration as input capture for timer */
gpio_setup_pin_af(PWM_INPUT2_GPIO_PORT, PWM_INPUT2_GPIO_PIN, PWM_INPUT2_GPIO_AF, FALSE);
/** TIM configuration: Input Capture mode
* Two IC signals are mapped to the same TI input
*/
timer_ic_set_input(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_PERIOD, PWM_INPUT2_TIMER_INPUT);
timer_ic_set_input(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_DUTY, PWM_INPUT2_TIMER_INPUT);
#if USE_PWM_INPUT2 == PWM_PULSE_TYPE_ACTIVE_LOW
timer_ic_set_polarity(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_PERIOD, TIM_IC_RISING);
timer_ic_set_polarity(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_DUTY, TIM_IC_FALLING);
#elif USE_PWM_INPUT2 == PWM_PULSE_TYPE_ACTIVE_HIGH
timer_ic_set_polarity(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_PERIOD, TIM_IC_FALLING);
timer_ic_set_polarity(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_DUTY, TIM_IC_RISING);
#endif
/* Select the valid trigger input */
timer_slave_set_trigger(PWM_INPUT2_TIMER, PWM_INPUT2_SLAVE_TRIG);
/* Configure the slave mode controller in reset mode */
timer_slave_set_mode(PWM_INPUT2_TIMER, TIM_SMCR_SMS_RM);
/* Enable timer Interrupt(s). */
nvic_set_priority(PWM_INPUT2_IRQ, PWM_INPUT_IRQ_PRIO);
nvic_enable_irq(PWM_INPUT2_IRQ);
#ifdef PWM_INPUT2_IRQ2
nvic_set_priority(PWM_INPUT2_IRQ2, PWM_INPUT_IRQ_PRIO);
nvic_enable_irq(PWM_INPUT2_IRQ2);
#endif
/* Enable the Capture/Compare and Update interrupt requests. */
timer_enable_irq(PWM_INPUT2_TIMER, (PWM_INPUT2_CC_IE | TIM_DIER_UIE));
/* Enable capture channel. */
timer_ic_enable(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_PERIOD);
timer_ic_enable(PWM_INPUT2_TIMER, PWM_INPUT2_CHANNEL_DUTY);
#endif
}
#if USE_PWM_INPUT_TIM1
#if defined(STM32F1)
void tim1_up_isr(void)
{
#elif defined(STM32F4)
void tim1_up_tim10_isr(void) {
#endif
if ((TIM1_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM1, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
void tim1_cc_isr(void) {
if ((TIM1_SR & TIM1_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM1, TIM1_CC_IF_PERIOD);
pwm_input_period_tics[TIM1_PWM_INPUT_IDX] = TIM1_CCR_PERIOD;
pwm_input_period_valid[TIM1_PWM_INPUT_IDX] = true;
}
if ((TIM1_SR & TIM1_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM1, TIM1_CC_IF_DUTY);
pwm_input_duty_tics[TIM1_PWM_INPUT_IDX] = TIM1_CCR_DUTY;
pwm_input_duty_valid[TIM1_PWM_INPUT_IDX] = true;
}
}
#endif
#if USE_PWM_INPUT_TIM2
void tim2_isr(void) {
if ((TIM2_SR & TIM2_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM2, TIM2_CC_IF_PERIOD);
pwm_input_period_tics[TIM2_PWM_INPUT_IDX] = TIM2_CCR_PERIOD;
pwm_input_period_valid[TIM2_PWM_INPUT_IDX] = true;
}
if ((TIM2_SR & TIM2_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM2, TIM2_CC_IF_DUTY);
pwm_input_duty_tics[TIM2_PWM_INPUT_IDX] = TIM2_CCR_DUTY;
pwm_input_duty_valid[TIM2_PWM_INPUT_IDX] = true;
}
if ((TIM2_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM2, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
#if USE_PWM_INPUT_TIM3
void tim3_isr(void) {
if ((TIM3_SR & TIM3_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM3, TIM3_CC_IF_PERIOD);
pwm_input_period_tics[TIM3_PWM_INPUT_IDX] = TIM3_CCR_PERIOD;
pwm_input_period_valid[TIM3_PWM_INPUT_IDX] = true;
}
if ((TIM3_SR & TIM3_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM3, TIM3_CC_IF_DUTY);
pwm_input_duty_tics[TIM3_PWM_INPUT_IDX] = TIM3_CCR_DUTY;
pwm_input_duty_valid[TIM3_PWM_INPUT_IDX] = true;
}
if ((TIM3_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM3, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
#if USE_PWM_INPUT_TIM4
void tim4_isr(void) {
if ((TIM4_SR & TIM4_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM4, TIM4_CC_IF_PERIOD);
pwm_input_period_tics[TIM4_PWM_INPUT_IDX] = TIM4_CCR_PERIOD;
pwm_input_period_valid[TIM4_PWM_INPUT_IDX] = true;
}
if ((TIM4_SR & TIM4_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM4, TIM4_CC_IF_DUTY);
pwm_input_duty_tics[TIM4_PWM_INPUT_IDX] = TIM4_CCR_DUTY;
pwm_input_duty_valid[TIM4_PWM_INPUT_IDX] = true;
}
if ((TIM4_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM4, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
#if USE_PWM_INPUT_TIM5
void tim5_isr(void) {
if ((TIM5_SR & TIM5_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM5, TIM5_CC_IF_PERIOD);
pwm_input_period_tics[TIM5_PWM_INPUT_IDX] = TIM5_CCR_PERIOD;
pwm_input_period_valid[TIM5_PWM_INPUT_IDX] = true;
}
if ((TIM5_SR & TIM5_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM5, TIM5_CC_IF_DUTY);
pwm_input_duty_tics[TIM5_PWM_INPUT_IDX] = TIM5_CCR_DUTY;
pwm_input_duty_valid[TIM5_PWM_INPUT_IDX] = true;
}
if ((TIM5_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM5, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif
#if USE_PWM_INPUT_TIM8
#if defined(STM32F1)
void tim8_up_isr(void)
{
#elif defined(STM32F4)
void tim8_up_tim13_isr(void) {
#endif
if ((TIM8_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM8, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
void tim8_cc_isr(void) {
if ((TIM8_SR & TIM8_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM8, TIM8_CC_IF_PERIOD);
pwm_input_period_tics[TIM8_PWM_INPUT_IDX] = TIM8_CCR_PERIOD;
pwm_input_period_valid[TIM8_PWM_INPUT_IDX] = true;
}
if ((TIM8_SR & TIM8_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM8, TIM8_CC_IF_DUTY);
pwm_input_duty_tics[TIM8_PWM_INPUT_IDX] = TIM8_CCR_DUTY;
pwm_input_duty_valid[TIM8_PWM_INPUT_IDX] = true;
}
}
#endif
#if USE_PWM_INPUT_TIM9
// TIM1 break interrupt (which we don't care here) and TIM9 global interrupt
void tim1_brk_tim9_isr(void) {
if ((TIM9_SR & TIM9_CC_IF_PERIOD) != 0) {
timer_clear_flag(TIM9, TIM9_CC_IF_PERIOD);
pwm_input_period_tics[TIM9_PWM_INPUT_IDX] = TIM9_CCR_PERIOD;
pwm_input_period_valid[TIM9_PWM_INPUT_IDX] = true;
}
if ((TIM9_SR & TIM9_CC_IF_DUTY) != 0) {
timer_clear_flag(TIM9, TIM9_CC_IF_DUTY);
pwm_input_duty_tics[TIM9_PWM_INPUT_IDX] = TIM9_CCR_DUTY;
pwm_input_duty_valid[TIM9_PWM_INPUT_IDX] = true;
}
if ((TIM9_SR & TIM_SR_UIF) != 0) {
timer_clear_flag(TIM9, TIM_SR_UIF);
// FIXME clear overflow interrupt but what else ?
}
}
#endif

View File

@@ -1,61 +0,0 @@
/*
* Copyright (C) 2014 Gautier Hattenberger
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_periph/pwm_input_arch.h
* @ingroup stm32_arch
*
* handling of smt32 PWM input using a timer with capture.
*/
#ifndef PWM_INPUT_ARCH_H
#define PWM_INPUT_ARCH_H
#include "std.h"
enum pwm_input_channels {
PWM_INPUT1,
PWM_INPUT2,
PWM_INPUT_NB
};
/**
* The default pwm counter is set-up to have 1/6 us resolution.
*
* The timer clock frequency (before prescaling):
* STM32F1:
* TIM1 -> APB2 = HCLK = 72MHz
* TIM2 -> 2 * APB1 = 2 * 36MHz = 72MHz
* STM32F4:
* TIM1 -> 2 * APB2 = 2 * 84MHz = 168MHz
* TIM2 -> 2 * APB1 = 2 * 42MHz = 84MHz
*/
#ifndef PWM_INPUT1_TICKS_PER_USEC
#define PWM_INPUT1_TICKS_PER_USEC 6
#endif
#ifndef PWM_INPUT2_TICKS_PER_USEC
#define PWM_INPUT2_TICKS_PER_USEC 6
#endif
#endif /* PWM_INPUT_ARCH_H */

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/** \file rng_arch.c
* \brief arch specific Random Number Generator API
*
*/
#include "mcu_periph/rng.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/rng.h>
uint32_t last;
void rng_init(void) {
rcc_periph_clock_enable(RCC_RNG);
rng_enable();
// dont forget to throw away the first generated number
last = rng_wait_and_get();
}
void rng_deinit(void) {
rng_disable();
rcc_periph_clock_disable(RCC_RNG);
}
// Return true only if we got a new number
// that is different from the previous one
bool rng_get(uint32_t *rand_nr) {
uint32_t tmp = 0;
if (rng_get_random(&tmp) && (tmp != last)) {
last = tmp;
*rand_nr = tmp;
return true;
} else {
return false;
}
}
// Wait until we get a new number that is different
// from the previous one. We can wait forever here if
// the clocks are not setup properly.
uint32_t rng_wait_and_get(void) {
uint32_t tmp = last;
while (tmp == last) {
tmp = rng_get_random_blocking();
}
last = tmp;
return tmp;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2005-2012 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/mcu_periph/spi_arch.h
* @ingroup stm32_arch
*
* Handling of SPI hardware for STM32.
*/
#ifndef SPI_ARCH_H
#define SPI_ARCH_H
#endif // SPI_ARCH_H

View File

@@ -1,160 +0,0 @@
/*
* Copyright (C) 2009-2011 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/sys_time_arch.c
* @ingroup stm32_arch
*
* STM32 timing functions.
*
*/
#include "mcu_periph/sys_time.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/cm3/systick.h>
#include "std.h"
#include "libopencm3/cm3/systick.h"
#ifdef SYS_TIME_LED
#include "led.h"
#endif
#ifndef USE_OCM3_SYSTICK_INIT
#define USE_OCM3_SYSTICK_INIT 1
#endif
void sys_tick_handler(void);
/** Initialize SysTick.
* Generate SysTick interrupt every sys_time.resolution_cpu_ticks
*/
void sys_time_arch_init(void)
{
/* run cortex systick timer with 72MHz (FIXME only 72 or does it work with 168MHz???) */
#if USE_OCM3_SYSTICK_INIT
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
#endif
sys_time.cpu_ticks_per_sec = AHB_CLK;
/* cpu ticks per desired sys_time timer step */
sys_time.resolution_cpu_ticks = (uint32_t)(sys_time.resolution * sys_time.cpu_ticks_per_sec + 0.5);
#if USE_OCM3_SYSTICK_INIT
/* The timer interrupt is activated on the transition from 1 to 0,
* therefore it activates every n+1 clock ticks.
*/
systick_set_reload(sys_time.resolution_cpu_ticks - 1);
systick_interrupt_enable();
systick_counter_enable();
#endif
}
uint32_t get_sys_time_usec(void)
{
return sys_time.nb_sec * 1000000 +
usec_of_cpu_ticks(sys_time.nb_sec_rem) +
usec_of_cpu_ticks(systick_get_reload() - systick_get_value());
}
uint32_t get_sys_time_usec100(void)
{
return sys_time.nb_sec * 10000 +
usec_of_cpu_ticks(sys_time.nb_sec_rem)/100 +
usec_of_cpu_ticks(systick_get_reload() - systick_get_value())/100;
}
uint32_t get_sys_time_msec(void)
{
return sys_time.nb_sec * 1000 +
msec_of_cpu_ticks(sys_time.nb_sec_rem) +
msec_of_cpu_ticks(systick_get_reload() - systick_get_value());
}
// FIXME : nb_tick rollover ???
//
// 97 days at 512hz
// 12 hours at 100khz
//
void sys_tick_handler(void)
{
sys_time.nb_tick++;
sys_time.nb_sec_rem += sys_time.resolution_cpu_ticks;
if (sys_time.nb_sec_rem >= sys_time.cpu_ticks_per_sec) {
sys_time.nb_sec_rem -= sys_time.cpu_ticks_per_sec;
sys_time.nb_sec++;
#ifdef SYS_TIME_LED
LED_TOGGLE(SYS_TIME_LED);
#endif
}
for (unsigned int i = 0; i < SYS_TIME_NB_TIMER; i++) {
if (sys_time.timer[i].in_use &&
sys_time.nb_tick >= sys_time.timer[i].end_time) {
sys_time.timer[i].end_time += sys_time.timer[i].duration;
sys_time.timer[i].elapsed = true;
if (sys_time.timer[i].cb) {
sys_time.timer[i].cb(i);
}
}
}
}
/** Busy wait in microseconds.
*
* max value is limited by the max number of cycle
* i.e 2^32 * usec_of_cpu_ticks(systick_get_reload())
*/
void sys_time_usleep(uint32_t us)
{
// start time
uint32_t start = systick_get_value();
// max time of one full counter cycle (n + 1 ticks)
uint32_t DT = usec_of_cpu_ticks(systick_get_reload() + 1);
// number of cycles
uint32_t n = us / DT;
// remaining number of cpu ticks
uint32_t rem = cpu_ticks_of_usec(us % DT);
// end time depend on the current value of the counter
uint32_t end;
if (rem < start) {
end = start - rem;
} else {
// one more count flag is required
n++;
end = systick_get_reload() - rem + start;
}
// count number of cycles (when counter reachs 0)
while (n) {
while (!systick_get_countflag());
n--;
}
// wait remaining ticks
while (systick_get_value() > end);
}
void sys_time_msleep(uint32_t ms) {
sys_time_usleep(ms*1000);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2009-2010 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/mcu_periph/uart_arch.h
* @ingroup stm32_arch
*
* Handling of UART hardware for STM32.
*/
#ifndef STM32_UART_ARCH_H
#define STM32_UART_ARCH_H
#define B1200 1200
#define B2400 2400
#define B4800 4800
#define B9600 9600
#define B19200 19200
#define B38400 38400
#define B57600 57600
#define B100000 100000
#define B115200 115200
#define B230400 230400
#define B460800 460800
#define B921600 921600
#define B1500000 1500000
#define B3000000 3000000
#define UART_SPEED(_def) _def
#endif /* STM32_UART_ARCH_H */

View File

@@ -1,183 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_dualpwm_arch.c
* STM32 dual PWM servos handling.
*/
//VALID TIMERS IS TIM5 ON THE LISA/M
#include "modules/actuators/actuators_shared_arch.h"
#include "modules/actuators/actuators_dualpwm_arch.h"
#include "modules/actuators/actuators_dualpwm.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_periph/gpio_arch.h"
uint32_t ratio_4ms, ratio_16ms;
uint32_t actuators_dualpwm_values[ACTUATORS_DUALPWM_NB];
/** PWM arch init called by generic pwm driver
*/
void actuators_dualpwm_arch_init(void)
{
/*-----------------------------------
* Configure timer peripheral clocks
*-----------------------------------*/
#if PWM_USE_TIM1
rcc_periph_clock_enable(RCC_TIM1);
#endif
#if PWM_USE_TIM2
rcc_periph_clock_enable(RCC_TIM2);
#endif
#if PWM_USE_TIM3
rcc_periph_clock_enable(RCC_TIM3);
#endif
#if PWM_USE_TIM4
rcc_periph_clock_enable(RCC_TIM4);
#endif
#if PWM_USE_TIM5
rcc_periph_clock_enable(RCC_TIM5);
#endif
#if PWM_USE_TIM8
rcc_periph_clock_enable(RCC_TIM8);
#endif
#if PWM_USE_TIM9
rcc_periph_clock_enable(RCC_TIM9);
#endif
#if PWM_USE_TIM12
rcc_periph_clock_enable(RCC_TIM12);
#endif
/*----------------
* Configure GPIO
*----------------*/
#ifdef DUAL_PWM_SERVO_5
gpio_setup_pin_af(DUAL_PWM_SERVO_5_GPIO, DUAL_PWM_SERVO_5_PIN, DUAL_PWM_SERVO_5_AF, TRUE);
#endif
#ifdef DUAL_PWM_SERVO_6
gpio_setup_pin_af(DUAL_PWM_SERVO_6_GPIO, DUAL_PWM_SERVO_6_PIN, DUAL_PWM_SERVO_6_AF, TRUE);
#endif
#if DUAL_PWM_USE_TIM5
rcc_periph_reset_pulse(RST_TIM5);
set_servo_timer(TIM5, TIM5_SERVO_HZ, PWM_TIM5_CHAN_MASK);
nvic_set_priority(NVIC_TIM5_IRQ, 2);
nvic_enable_irq(NVIC_TIM5_IRQ);
timer_enable_irq(TIM5, TIM_DIER_CC1IE);
#endif
//calculation the values to put into the timer registers to generate pulses every 4ms and 16ms.
ratio_4ms = (ONE_MHZ_CLK / 250) - 1;
ratio_16ms = (ONE_MHZ_CLK / 62.5) - 1;
}
/** Interuption called at the end of the timer. In our case alternatively very 4ms and 16ms (twice every 20ms)
*/
#if DUAL_PWM_USE_TIM5
void tim5_isr(void)
{
dual_pwm_isr();
}
#endif
/** Fonction that clears the flag of interuption in order to reactivate the interuption
*/
void clear_timer_flag(void)
{
#if DUAL_PWM_USE_TIM5
timer_clear_flag(TIM5, TIM_SR_CC1IF);
#endif
}
void set_dual_pwm_timer_s_period(uint32_t period)
{
#if DUAL_PWM_USE_TIM5
timer_set_period(TIM5, period);
#endif
}
void set_dual_pwm_timer_s_oc(uint32_t oc_value, uint32_t oc_value2)
{
#if DUAL_PWM_USE_TIM5
timer_set_oc_value(DUAL_PWM_SERVO_5_TIMER, DUAL_PWM_SERVO_5_OC, oc_value);
timer_set_oc_value(DUAL_PWM_SERVO_6_TIMER, DUAL_PWM_SERVO_6_OC, oc_value2);
#endif
}
void dual_pwm_isr(void)
{
static int num_pulse = 0; //status of the timer. Are we controling the first or the second servo
clear_timer_flag();
if (num_pulse == 1) {
set_dual_pwm_timer_s_period(ratio_16ms);
set_dual_pwm_timer_s_oc(actuators_dualpwm_values[DUAL_PWM_SERVO_5_P1],actuators_dualpwm_values[DUAL_PWM_SERVO_5_P2]);
num_pulse = 0;
} else {
set_dual_pwm_timer_s_period(ratio_4ms);
set_dual_pwm_timer_s_oc(actuators_dualpwm_values[DUAL_PWM_SERVO_6_P1],actuators_dualpwm_values[DUAL_PWM_SERVO_6_P2]);
num_pulse = 1;
}
}
void actuators_dualpwm_set(uint8_t idx, int16_t value)
{
actuators_dualpwm_values[idx] = value;
}
/** Set pulse widths from actuator values, assumed to be in us
*/
void actuators_dualpwm_commit(void)
{
//we don't need to commit the values into this function as far as it's done in the interuption
//(wich is called every 4ms and 16ms alternatively (twice every 20ms))
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_dualpwm_arch.h
* STM32 PWM servos handling.
*/
#ifndef ACTUATORS_dualpwm_ARCH_H
#define ACTUATORS_dualpwm_ARCH_H
#include "std.h"
#include BOARD_CONFIG
// Max 2 dualpwm channels of 2 pulses each
#ifndef ACTUATORS_DUALPWM_NB
#define ACTUATORS_DUALPWM_NB 4
#endif
extern uint32_t actuators_dualpwm_values[ACTUATORS_DUALPWM_NB];
extern void actuators_dualpwm_set(uint8_t idx, int16_t value);
extern void actuators_dualpwm_commit(void);
extern void dual_pwm_isr(void);
extern void clear_timer_flag(void);
extern void set_dual_pwm_timer_s_period(uint32_t period);
extern void set_dual_pwm_timer_s_oc(uint32_t oc_value, uint32_t oc_value2);
#define SERVOS_TICS_OF_USEC(_v) (_v)
#define ActuatorDualpwmSet actuators_dualpwm_set
#define ActuatorsDualpwmCommit actuators_dualpwm_commit
#endif /* ACTUATORS_dualpwm_ARCH_H */

View File

@@ -1,195 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_pwm_arch.c
* STM32 PWM servos handling.
*/
//VALID TIMERS ARE TIM1,2,3,4,5,8,9,12
#include "modules/actuators/actuators_shared_arch.h"
#include "modules/actuators/actuators_pwm_arch.h"
#include "modules/actuators/actuators_pwm.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include "mcu_periph/gpio_arch.h"
/** PWM arch init called by generic pwm driver
*/
void actuators_pwm_arch_init(void)
{
/*-----------------------------------
* Configure timer peripheral clocks
*-----------------------------------*/
#if PWM_USE_TIM1
rcc_periph_clock_enable(RCC_TIM1);
#endif
#if PWM_USE_TIM2
rcc_periph_clock_enable(RCC_TIM2);
#endif
#if PWM_USE_TIM3
rcc_periph_clock_enable(RCC_TIM3);
#endif
#if PWM_USE_TIM4
rcc_periph_clock_enable(RCC_TIM4);
#endif
#if PWM_USE_TIM5
rcc_periph_clock_enable(RCC_TIM5);
#endif
#if PWM_USE_TIM8
rcc_periph_clock_enable(RCC_TIM8);
#endif
#if PWM_USE_TIM9
rcc_periph_clock_enable(RCC_TIM9);
#endif
#if PWM_USE_TIM12
rcc_periph_clock_enable(RCC_TIM12);
#endif
/*----------------
* Configure GPIO
*----------------*/
#ifdef PWM_SERVO_0
gpio_setup_pin_af(PWM_SERVO_0_GPIO, PWM_SERVO_0_PIN, PWM_SERVO_0_AF, TRUE);
#endif
#ifdef PWM_SERVO_1
gpio_setup_pin_af(PWM_SERVO_1_GPIO, PWM_SERVO_1_PIN, PWM_SERVO_1_AF, TRUE);
#endif
#ifdef PWM_SERVO_2
gpio_setup_pin_af(PWM_SERVO_2_GPIO, PWM_SERVO_2_PIN, PWM_SERVO_2_AF, TRUE);
#endif
#ifdef PWM_SERVO_3
gpio_setup_pin_af(PWM_SERVO_3_GPIO, PWM_SERVO_3_PIN, PWM_SERVO_3_AF, TRUE);
#endif
#ifdef PWM_SERVO_4
gpio_setup_pin_af(PWM_SERVO_4_GPIO, PWM_SERVO_4_PIN, PWM_SERVO_4_AF, TRUE);
#endif
#ifdef PWM_SERVO_5
gpio_setup_pin_af(PWM_SERVO_5_GPIO, PWM_SERVO_5_PIN, PWM_SERVO_5_AF, TRUE);
#endif
#ifdef PWM_SERVO_6
gpio_setup_pin_af(PWM_SERVO_6_GPIO, PWM_SERVO_6_PIN, PWM_SERVO_6_AF, TRUE);
#endif
#ifdef PWM_SERVO_7
gpio_setup_pin_af(PWM_SERVO_7_GPIO, PWM_SERVO_7_PIN, PWM_SERVO_7_AF, TRUE);
#endif
#ifdef PWM_SERVO_8
gpio_setup_pin_af(PWM_SERVO_8_GPIO, PWM_SERVO_8_PIN, PWM_SERVO_8_AF, TRUE);
#endif
#ifdef PWM_SERVO_9
gpio_setup_pin_af(PWM_SERVO_9_GPIO, PWM_SERVO_9_PIN, PWM_SERVO_9_AF, TRUE);
#endif
#ifdef PWM_SERVO_10
gpio_setup_pin_af(PWM_SERVO_10_GPIO, PWM_SERVO_10_PIN, PWM_SERVO_10_AF, TRUE);
#endif
#ifdef PWM_SERVO_11
gpio_setup_pin_af(PWM_SERVO_11_GPIO, PWM_SERVO_11_PIN, PWM_SERVO_11_AF, TRUE);
#endif
#if PWM_USE_TIM1
rcc_periph_reset_pulse(RST_TIM1);
set_servo_timer(TIM1, TIM1_SERVO_HZ, PWM_TIM1_CHAN_MASK);
#endif
#if PWM_USE_TIM2
rcc_periph_reset_pulse(RST_TIM2);
set_servo_timer(TIM2, TIM2_SERVO_HZ, PWM_TIM2_CHAN_MASK);
#endif
#if PWM_USE_TIM3
rcc_periph_reset_pulse(RST_TIM3);
set_servo_timer(TIM3, TIM3_SERVO_HZ, PWM_TIM3_CHAN_MASK);
#endif
#if PWM_USE_TIM4
rcc_periph_reset_pulse(RST_TIM4);
set_servo_timer(TIM4, TIM4_SERVO_HZ, PWM_TIM4_CHAN_MASK);
#endif
#if PWM_USE_TIM5
rcc_periph_reset_pulse(RST_TIM5);
set_servo_timer(TIM5, TIM5_SERVO_HZ, PWM_TIM5_CHAN_MASK);
#endif
#if PWM_USE_TIM8
rcc_periph_reset_pulse(RST_TIM8);
set_servo_timer(TIM8, TIM8_SERVO_HZ, PWM_TIM8_CHAN_MASK);
#endif
#if PWM_USE_TIM9
rcc_periph_reset_pulse(RST_TIM9);
set_servo_timer(TIM9, TIM9_SERVO_HZ, PWM_TIM9_CHAN_MASK);
#endif
#if PWM_USE_TIM12
rcc_periph_reset_pulse(RST_TIM12);
set_servo_timer(TIM12, TIM12_SERVO_HZ, PWM_TIM12_CHAN_MASK);
#endif
}
/** Set pulse widths from actuator values, assumed to be in us
*/
void actuators_pwm_arch_commit(void)
{
#ifdef PWM_SERVO_0
timer_set_oc_value(PWM_SERVO_0_TIMER, PWM_SERVO_0_OC, actuators_pwm_values[PWM_SERVO_0]);
#endif
#ifdef PWM_SERVO_1
timer_set_oc_value(PWM_SERVO_1_TIMER, PWM_SERVO_1_OC, actuators_pwm_values[PWM_SERVO_1]);
#endif
#ifdef PWM_SERVO_2
timer_set_oc_value(PWM_SERVO_2_TIMER, PWM_SERVO_2_OC, actuators_pwm_values[PWM_SERVO_2]);
#endif
#ifdef PWM_SERVO_3
timer_set_oc_value(PWM_SERVO_3_TIMER, PWM_SERVO_3_OC, actuators_pwm_values[PWM_SERVO_3]);
#endif
#ifdef PWM_SERVO_4
timer_set_oc_value(PWM_SERVO_4_TIMER, PWM_SERVO_4_OC, actuators_pwm_values[PWM_SERVO_4]);
#endif
#ifdef PWM_SERVO_5
timer_set_oc_value(PWM_SERVO_5_TIMER, PWM_SERVO_5_OC, actuators_pwm_values[PWM_SERVO_5]);
#endif
#ifdef PWM_SERVO_6
timer_set_oc_value(PWM_SERVO_6_TIMER, PWM_SERVO_6_OC, actuators_pwm_values[PWM_SERVO_6]);
#endif
#ifdef PWM_SERVO_7
timer_set_oc_value(PWM_SERVO_7_TIMER, PWM_SERVO_7_OC, actuators_pwm_values[PWM_SERVO_7]);
#endif
#ifdef PWM_SERVO_8
timer_set_oc_value(PWM_SERVO_8_TIMER, PWM_SERVO_8_OC, actuators_pwm_values[PWM_SERVO_8]);
#endif
#ifdef PWM_SERVO_9
timer_set_oc_value(PWM_SERVO_9_TIMER, PWM_SERVO_9_OC, actuators_pwm_values[PWM_SERVO_9]);
#endif
#ifdef PWM_SERVO_10
timer_set_oc_value(PWM_SERVO_10_TIMER, PWM_SERVO_10_OC, actuators_pwm_values[PWM_SERVO_10]);
#endif
#ifdef PWM_SERVO_11
timer_set_oc_value(PWM_SERVO_11_TIMER, PWM_SERVO_11_OC, actuators_pwm_values[PWM_SERVO_11]);
#endif
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_pwm_arch.h
* STM32 PWM servos handling.
*/
#ifndef ACTUATORS_PWM_ARCH_H
#define ACTUATORS_PWM_ARCH_H
#include "std.h"
#include BOARD_CONFIG
#define SERVOS_TICS_OF_USEC(_v) (_v)
#endif /* ACTUATORS_PWM_ARCH_H */

View File

@@ -1,122 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_shared_arch.c
* STM32 PWM and dualPWM servos shared functions.
*/
#include "arch/stm32/modules/actuators/actuators_shared_arch.h"
#include <libopencm3/stm32/timer.h>
// for timer_get_frequency
#include "arch/stm32/mcu_arch.h"
/** Set PWM channel configuration
*/
void actuators_pwm_arch_channel_init(uint32_t timer_peripheral,
enum tim_oc_id oc_id)
{
timer_disable_oc_output(timer_peripheral, oc_id);
//There is no such register in TIM9 and 12.
if (timer_peripheral != TIM9 && timer_peripheral != TIM12) {
timer_disable_oc_clear(timer_peripheral, oc_id);
}
timer_enable_oc_preload(timer_peripheral, oc_id);
timer_set_oc_slow_mode(timer_peripheral, oc_id);
timer_set_oc_mode(timer_peripheral, oc_id, TIM_OCM_PWM1);
timer_set_oc_polarity_high(timer_peripheral, oc_id);
timer_enable_oc_output(timer_peripheral, oc_id);
// Used for TIM1 and TIM8, the function does nothing if other timer is specified.
timer_enable_break_main_output(timer_peripheral);
}
/** Set Timer configuration
* @param[in] timer Timer register address base
* @param[in] freq PWM frequency in Hz (1 / auto-reload period)
* @param[in] channels_mask output compare channels to enable
*/
void set_servo_timer(uint32_t timer, uint32_t freq, uint8_t channels_mask)
{
/* Timer global mode:
* - No divider.
* - Alignement edge.
* - Direction up.
*/
if ((timer == TIM9) || (timer == TIM12))
//There are no EDGE and DIR settings in TIM9 and TIM12
{
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
} else {
timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
}
// By default the PWM_BASE_FREQ is set to 1MHz thus the timer tick period is 1uS
uint32_t timer_clk = timer_get_frequency(timer);
timer_set_prescaler(timer, (timer_clk / PWM_BASE_FREQ) - 1);
timer_disable_preload(timer);
timer_continuous_mode(timer);
timer_set_period(timer, (PWM_BASE_FREQ / freq) - 1);
/* Disable outputs and configure channel if needed. */
if (bit_is_set(channels_mask, 0)) {
actuators_pwm_arch_channel_init(timer, TIM_OC1);
}
if (bit_is_set(channels_mask, 1)) {
actuators_pwm_arch_channel_init(timer, TIM_OC2);
}
if (bit_is_set(channels_mask, 2)) {
actuators_pwm_arch_channel_init(timer, TIM_OC3);
}
if (bit_is_set(channels_mask, 3)) {
actuators_pwm_arch_channel_init(timer, TIM_OC4);
}
/*
* Set initial output compare values.
* Note: Maybe we should preload the compare registers with some sensible
* values before we enable the timer?
*/
//timer_set_oc_value(timer, TIM_OC1, 1000);
//timer_set_oc_value(timer, TIM_OC2, 1000);
//timer_set_oc_value(timer, TIM_OC3, 1000);
//timer_set_oc_value(timer, TIM_OC4, 1000);
/* -- Enable timer -- */
/*
* ARR reload enable.
* Note: In our case it does not matter much if we do preload or not. As it
* is unlikely we will want to change the frequency of the timer during
* runtime anyways.
*/
timer_enable_preload(timer);
/* Counter enable. */
timer_enable_counter(timer);
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file arch/stm32/modules/actuators/actuators_shared_arch.h
* STM32 PWM and dualPWM servos shared functions.
*/
#ifndef ACTUATORS_PWM_SHARED_ARCH_H
#define ACTUATORS_PWM_SHARED_ARCH_H
#include "std.h"
#include BOARD_CONFIG
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_arch.h"
#define ONE_MHZ_CLK 1000000
/* Default timer base frequency is 1MHz */
#if ! defined(PWM_BASE_FREQ)
#define PWM_BASE_FREQ ONE_MHZ_CLK
#endif
/** Default servo update rate in Hz */
#ifndef SERVO_HZ
#define SERVO_HZ 40
#endif
// Update rate can be adapted for each timer
#ifndef TIM1_SERVO_HZ
#define TIM1_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM2_SERVO_HZ
#define TIM2_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM3_SERVO_HZ
#define TIM3_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM4_SERVO_HZ
#define TIM4_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM5_SERVO_HZ
#define TIM5_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM8_SERVO_HZ
#define TIM8_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM9_SERVO_HZ
#define TIM9_SERVO_HZ SERVO_HZ
#endif
#ifndef TIM12_SERVO_HZ
#define TIM12_SERVO_HZ SERVO_HZ
#endif
extern void actuators_pwm_arch_channel_init(uint32_t timer_peripheral, enum tim_oc_id oc_id);
extern void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask);
#endif /* ACTUATORS_PWM_SHARED_ARCH_H */

View File

@@ -1,320 +0,0 @@
/*
* Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/**
* @file arch/stm32/modules/core/settings_arch.c
* Persistent settings low level flash routines stm32.
*
* data flash_addr
* data_size flash_end - FSIZ
* checksum flash_end - FCHK
*
* STM32: minimum write size 2 bytes, endurance 10k cycles,
* max sector erase time 40ms, max prog time 70us per 2 bytes
*/
#include "modules/core/settings.h"
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/crc.h>
#include <libopencm3/stm32/dbgmcu.h>
struct FlashInfo {
uint32_t addr;
uint32_t total_size;
uint32_t page_nr;
uint32_t page_size;
};
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size);
static int32_t flash_detect(struct FlashInfo *flash);
static int32_t pflash_program_bytes(struct FlashInfo *flash,
uint32_t src,
uint32_t size,
uint32_t chksum);
#if defined(STM32F1)
#define FLASH_SIZE_ MMIO16(0x1FFFF7E0)
#elif defined(STM32F4)
#define FLASH_SIZE_ MMIO16(0x1FFF7A22)
#endif
#define FLASH_BEGIN 0x08000000
#define FSIZ 8
#define FCHK 4
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size)
{
uint32_t i;
/* reset crc */
CRC_CR = CRC_CR_RESET;
if (ptr % 4) {
/* calc in 8bit chunks */
for (i = 0; i < (size & ~3); i += 4) {
CRC_DR = (*(uint8_t *)(ptr + i)) |
(*(uint8_t *)(ptr + i + 1)) << 8 |
(*(uint8_t *)(ptr + i + 2)) << 16 |
(*(uint8_t *)(ptr + i + 3)) << 24;
}
} else {
/* calc in 32bit */
for (i = 0; i < (size & ~3); i += 4) {
CRC_DR = *(uint32_t *)(ptr + i);
}
}
/* remaining bytes */
switch (size % 4) {
case 1:
CRC_DR = *(uint8_t *)(ptr + i);
break;
case 2:
CRC_DR = (*(uint8_t *)(ptr + i)) |
(*(uint8_t *)(ptr + i + 1)) << 8;
break;
case 3:
CRC_DR = (*(uint8_t *)(ptr + i)) |
(*(uint8_t *)(ptr + i + 1)) << 8 |
(*(uint8_t *)(ptr + i + 2)) << 16;
break;
default:
break;
}
return CRC_DR;
}
static int32_t flash_detect(struct FlashInfo *flash)
{
flash->total_size = FLASH_SIZE_ * 0x400;
#if defined(STM32F1)
/* FIXME This will not work for connectivity line (needs ID, see below), but
device ID is only readable when freshly loaded through JTAG?! */
/* WARNING If you are using this for F4 this only works for memory sizes
* larger than 128kb. Otherwise the first few sectors are either 16kb or
* 64kb. To make those small devices work we would need to know what the page
* we want to put the settings into is. Otherwise we will might be writing
* into a 64kb page that is actually 16kb big.
*/
switch (flash->total_size) {
/* low density */
case 0x00004000: /* 16 kBytes */
case 0x00008000: /* 32 kBytes */
/* medium density, e.g. STM32F103RBT6 (Olimex STM32-H103) */
case 0x00010000: /* 64 kBytes */
case 0x00020000: { /* 128 kBytes */
flash->page_size = 0x400;
break;
}
/* high density, e.g. STM32F103RE (Joby Lisa/M, Lisa/L) */
case 0x00040000: /* 256 kBytes */
case 0x00080000: /* 512 kBytes */
/* XL density */
case 0x000C0000: /* 768 kBytes */
case 0x00100000: { /* 1 MByte */
flash->page_size = 0x800;
break;
}
default: {return -1;}
}
#elif defined(STM32F4) /* this is the correct way of detecting page sizes but we currently only use it for the F4 because the F1 version is broken. */
uint32_t device_id;
/* read device id */
device_id = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK;
switch (device_id) {
/* low density */
case 0x412:
/* medium density, e.g. STM32F103RB (Olimex STM32-H103) */
case 0x410: {
flash->page_size = 0x400;
break;
}
/* high density, e.g. STM32F103RE (Joby Lisa/L) */
case 0x414:
/* XL density */
case 0x430:
/* connectivity line */
case 0x418: {
flash->page_size = 0x800;
break;
}
case 0x0413: /* STM32F405xx/07xx and STM32F415xx/17xx) */
case 0x0419: /* STM32F42xxx and STM32F43xxx */
case 0x0423: /* STM32F401xB/C */
case 0x0433: /* STM32F401xD/E */
case 0x0431: { /* STM32F411xC/E */
flash->page_size = 0x20000;
break;
}
default: return -1;
}
switch (flash->total_size) {
case 0x00004000: /* 16 kBytes */
case 0x00008000: /* 32 kBytes */
case 0x00010000: /* 64 kBytes */
case 0x00020000: /* 128 kBytes */
case 0x00040000: /* 256 kBytes */
case 0x00080000: /* 512 kBytes */
case 0x000C0000: /* 768 kBytes */
case 0x00100000: /* 1 MByte */
case 0x00200000: /* 2 MByte */
break;
default: return -1;
}
#else
#error Unknown device
#endif
#if defined(STM32F1)
flash->page_nr = (flash->total_size / flash->page_size) - 1;
flash->addr = FLASH_BEGIN + flash->page_nr * flash->page_size;
#elif defined(STM32F4)
/* We are assuming all pages are 128kb so we have to compensate for the first
* few pages that are smaller which means we have to skip the first 4.
*/
flash->page_nr = (flash->total_size / flash->page_size) - 1 + 4;
flash->addr = FLASH_BEGIN + (flash->page_nr - 4) * flash->page_size;
#endif
return 0;
}
static int32_t pflash_erase(struct FlashInfo *flash)
{
uint32_t i;
/* erase */
flash_unlock();
#if defined(STM32F1)
flash_erase_page(flash->addr);
#elif defined(STM32F4)
flash_erase_sector(flash->page_nr, FLASH_CR_PROGRAM_X32);
#endif
flash_lock();
/* verify erase */
for (i = 0; i < flash->page_size; i += 4) {
if ((*(uint32_t *)(flash->addr + i)) != 0xFFFFFFFF) { return -1; }
}
return 0;
}
// (gdb) p *flash
// $1 = {addr = 134739968, total_size = 524288, page_nr = 255, page_size = 2048}
// 0x807F800 0x80000
static int32_t pflash_program_bytes(struct FlashInfo *flash,
uint32_t src,
uint32_t size,
uint32_t chksum)
{
uint32_t i;
/* erase, return with error if not successful */
if (pflash_erase(flash)) { return -1; }
flash_unlock();
/* write full 16 bit words */
for (i = 0; i < (size & ~1); i += 2) {
flash_program_half_word(flash->addr + i,
(uint16_t)(*(uint8_t *)(src + i) | (*(uint8_t *)(src + i + 1)) << 8));
}
/* fill bytes with a zero */
if (size & 1) {
flash_program_half_word(flash->addr + i, (uint16_t)(*(uint8_t *)(src + i)));
}
/* write size */
flash_program_half_word(flash->addr + flash->page_size - FSIZ,
(uint16_t)(size & 0xFFFF));
flash_program_half_word(flash->addr + flash->page_size - FSIZ + 2,
(uint16_t)((size >> 16) & 0xFFFF));
/* write checksum */
flash_program_half_word(flash->addr + flash->page_size - FCHK,
(uint16_t)(chksum & 0xFFFF));
flash_program_half_word(flash->addr + flash->page_size - FCHK + 2,
(uint16_t)((chksum >> 16) & 0xFFFF));
flash_lock();
/* verify data */
for (i = 0; i < size; i++) {
if ((*(uint8_t *)(flash->addr + i)) != (*(uint8_t *)(src + i))) { return -2; }
}
if (*(uint32_t *)(flash->addr + flash->page_size - FSIZ) != size) { return -3; }
if (*(uint32_t *)(flash->addr + flash->page_size - FCHK) != chksum) { return -4; }
return 0;
}
int32_t persistent_write(void *ptr, uint32_t size)
{
struct FlashInfo flash_info;
if (flash_detect(&flash_info)) { return -1; }
if ((size > flash_info.page_size - FSIZ) || (size == 0)) { return -2; }
return pflash_program_bytes(&flash_info,
(uint32_t)ptr,
size,
pflash_checksum((uint32_t)ptr, size));
}
int32_t persistent_read(void *ptr, uint32_t size)
{
struct FlashInfo flash;
uint32_t i;
/* check parameters */
if (flash_detect(&flash)) { return -1; }
if ((size > flash.page_size - FSIZ) || (size == 0)) { return -2; }
/* check consistency */
if (size != *(uint32_t *)(flash.addr + flash.page_size - FSIZ)) { return -3; }
if (pflash_checksum(flash.addr, size) !=
*(uint32_t *)(flash.addr + flash.page_size - FCHK)) {
return -4;
}
/* copy data */
for (i = 0; i < size; i++) {
*(uint8_t *)((uint32_t)ptr + i) = *(uint8_t *)(flash.addr + i);
}
return 0;
}
int32_t persistent_clear(void)
{
struct FlashInfo flash_info;
if (flash_detect(&flash_info)) { return -1; }
return pflash_erase(&flash_info);
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) 2025 The Paparazzi Team
*
* This file is part of paparazzi.
*
* Paparazzi 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.
*
* See LICENSE file for the full license version, or see http://www.gnu.org/licenses/
*/
#include "modules/core/threads.h"
#include "modules/core/threads_arch.h"
#include "stdbool.h"
#include "mcu_periph/sys_time.h"
int pprz_mtx_init(pprz_mutex_t* mtx) {
(void)mtx;
return 0;
}
int pprz_mtx_lock(pprz_mutex_t* mtx) {
(void)mtx;
return 0;
}
int pprz_mtx_trylock(pprz_mutex_t* mtx) {
(void)mtx;
(void)mtx;
return 0;
}
int pprz_mtx_unlock(pprz_mutex_t* mtx) {
(void)mtx;
return 0;
}
void pprz_bsem_init(pprz_bsem_t* bsem, bool taken) {
bsem->value = taken ? 0: 1;
}
void pprz_bsem_wait(pprz_bsem_t* bsem) {
while (bsem->value == 0)
{
// active wait
asm("NOP");
}
bsem->value = 0;
}
int pprz_bsem_wait_timeout(pprz_bsem_t* bsem, float timeout) {
float time_end = get_sys_time_float() + timeout;
while(get_sys_time_float() - time_end > 0) {
// active wait
if(bsem->value) {
bsem->value = 0;
return 0;
}
}
return -1;
}
void pprz_bsem_signal(pprz_bsem_t* bsem) {
bsem->value = 1;
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright (C) 2025 The Paparazzi Team
*
* This file is part of paparazzi.
*
* Paparazzi 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.
*
* See LICENSE file for the full license version, or see http://www.gnu.org/licenses/
*/
#pragma once
#define PPRZ_NORMAL_PRIO NORMALPRIO
#define THREADS_ATTRIBUTES __attribute__((error("Threads cannot be used in STM32 bare metal ARCH.")))
struct pprzMutex {
int dummy; // avoid warning: empty declaration
};
struct pprzBSem {
volatile int value;
};
typedef int pprz_thread_t;

View File

@@ -1,117 +0,0 @@
#include "modules/imu/imu.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/dma.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_periph/i2c.h"
#ifndef STM32F1
#error "imu_aspirin_arch arch currently only implemented for STM32F1"
#endif
void imu_aspirin_arch_int_enable(void)
{
#ifdef ASPIRIN_USE_GYRO_INT
nvic_set_priority(NVIC_EXTI15_10_IRQ, 0x0F);
nvic_enable_irq(NVIC_EXTI15_10_IRQ);
#endif
nvic_set_priority(NVIC_EXTI2_IRQ, 0x0F);
nvic_enable_irq(NVIC_EXTI2_IRQ);
// should not be needed anymore, handled by the spi driver
#if 0
/* Enable DMA1 channel4 IRQ Channel ( SPI RX) */
nvic_set_priority(NVIC_DMA1_CHANNEL4_IRQ, 0);
nvic_enable_irq(NVIC_DMA1_CHANNEL4_IRQ);
#endif
}
void imu_aspirin_arch_int_disable(void)
{
#ifdef ASPIRIN_USE_GYRO_INT
nvic_disable_irq(NVIC_EXTI15_10_IRQ);
#endif
nvic_disable_irq(NVIC_EXTI2_IRQ);
// should not be needed anymore, handled by the spi driver
#if 0
/* Enable DMA1 channel4 IRQ Channel ( SPI RX) */
nvic_disable_irq(NVIC_DMA1_CHANNEL4_IRQ);
#endif
}
void imu_aspirin_arch_init(void)
{
// This was needed for Lisa/L????
#if 0
/* Set "mag ss" and "mag reset" as floating inputs ------------------------*/
/* "mag ss" (PC12) is shorted to I2C2 SDA */
/* "mag reset" (PC13) is shorted to I2C2 SCL */
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set_mode(GPIOC, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO12 | GPIO13);
#endif
/* Gyro --------------------------------------------------------------------*/
/* configure external interrupt exti15_10 on PC14( gyro int ) */
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_AFIO);
gpio_set_mode(GPIOC, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO14);
#ifdef ASPIRIN_USE_GYRO_INT
exti_select_source(EXTI14, GPIOC);
exti_set_trigger(EXTI14, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI14);
#endif
/* configure external interrupt exti2 on PB2( accel int ) */
rcc_periph_clock_enable(RCC_GPIOB);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO2);
exti_select_source(EXTI2, GPIOB);
exti_set_trigger(EXTI2, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI2);
}
/****** the interrupts should be handled in the peripheral drivers *******/
/*
* Gyro data ready
*/
void exti15_10_isr(void)
{
/* clear EXTI */
exti_reset_request(EXTI14);
#ifdef ASPIRIN_USE_GYRO_INT
imu_aspirin.gyro_eoc = true;
imu_aspirin.status = AspirinStatusReadingGyro;
#endif
}
/*
* Accel data ready
*/
void exti2_isr(void)
{
/* clear EXTI */
exti_reset_request(EXTI2);
//adxl345_start_reading_data();
}

View File

@@ -1,18 +0,0 @@
#ifndef IMU_ASPIRIN_ARCH_H
#define IMU_ASPIRIN_ARCH_H
#include "modules/imu/imu.h"
#include <libopencm3/stm32/gpio.h>
extern void imu_aspirin_arch_int_enable(void);
extern void imu_aspirin_arch_int_disable(void);
// gyro eoc
static inline int imu_aspirin_eoc(void)
{
return (gpio_get(GPIOC, GPIO14) == 0);
}
#endif /* IMU_ASPIRIN_ARCH_H */

View File

@@ -1,43 +0,0 @@
/* $Id: link_mcu_hw.h 2064 2007-11-23 12:35:50Z hecto $
*
* Copyright (C) 2003-2005 Pascal Brisset, Antoine Drouin
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/** \brief handling of arm7 inter mcu link
*
*/
#ifndef LINK_MCU_HW_H
#define LINK_MCU_HW_H
#define CRC_INIT 0x0
#define CrcLow(x) ((x)&0xff)
#define CrcHigh(x) ((x)>>8)
static inline uint16_t CrcUpdate(uint16_t crc, uint8_t data)
{
uint8_t a = ((uint8_t)CrcHigh(crc)) + data;
uint8_t b = ((uint8_t)CrcLow(crc)) + a;
crc = b | a << 8;
return crc;
}
#endif /* LINK_MCU_HW_H */

View File

@@ -1,312 +0,0 @@
/*
* Copyright (C) 2010-2014 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* @file arch/stm32/modules/radio_control/ppm_arch.c
* @ingroup stm32_arch
*
* STM32 ppm decoder.
*
* Input signal either on:
* - PA1 TIM2/CH2 (uart1 trig on Lisa/L) (Servo 6 on Lisa/M)
* - PA10 TIM1/CH3 (uart1 trig on Lisa/L) (uart1 rx on Lisa/M)
*
*/
#include "modules/radio_control/radio_control.h"
#include "modules/radio_control/ppm.h"
#include BOARD_CONFIG
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_periph/gpio.h"
// for timer_get_frequency
#include "mcu_arch.h"
#define ONE_MHZ_CLK 1000000
#ifdef NVIC_TIM_IRQ_PRIO
#define PPM_IRQ_PRIO NVIC_TIM_IRQ_PRIO
#else
#define PPM_IRQ_PRIO 2
#endif
static uint32_t timer_rollover_cnt;
#if USE_PPM_TIM1
PRINT_CONFIG_MSG("Using TIM1 for PPM input.")
#define PPM_TIMER TIM1
#define RCC_TIM_PPM RCC_TIM1
#define RST_TIM_PPM RST_TIM1
#elif USE_PPM_TIM2
PRINT_CONFIG_MSG("Using TIM2 for PPM input.")
#define PPM_TIMER TIM2
#define RCC_TIM_PPM RCC_TIM2
#define RST_TIM_PPM RST_TIM2
#elif USE_PPM_TIM3
PRINT_CONFIG_MSG("Using TIM3 for PPM input.")
#define PPM_TIMER TIM3
#define RCC_TIM_PPM RCC_TIM3
#define RST_TIM_PPM RST_TIM3
#elif USE_PPM_TIM4
PRINT_CONFIG_MSG("Using TIM4 for PPM input.")
#define PPM_TIMER TIM4
#define RCC_TIM_PPM RCC_TIM4
#define RST_TIM_PPM RST_TIM4
#elif USE_PPM_TIM5
PRINT_CONFIG_MSG("Using TIM5 for PPM input.")
#define PPM_TIMER TIM5
#define RCC_TIM_PPM RCC_TIM5
#define RST_TIM_PPM RST_TIM5
#elif USE_PPM_TIM8
PRINT_CONFIG_MSG("Using TIM8 for PPM input.")
#define PPM_TIMER TIM8
#define RCC_TIM_PPM RCC_TIM8
#define RST_TIM_PPM RST_TIM8
#elif USE_PPM_TIM9
PRINT_CONFIG_MSG("Using TIM9 for PPM input.")
#define PPM_TIMER TIM9
#define RCC_TIM_PPM RCC_TIM9
#define RST_TIM_PPM RST_TIM9
#elif USE_PPM_TIM12
PRINT_CONFIG_MSG("Using TIM12 for PPM input.")
#define PPM_TIMER TIM12
#define RCC_TIM_PPM RCC_TIM12
#define RST_TIM_PPM RST_TIM12
#else
#error Unknown PPM input timer configuration.
#endif
void ppm_arch_init(void)
{
/* timer clock enable */
rcc_periph_clock_enable(RCC_TIM_PPM);
/* GPIO configuration as input capture for timer */
gpio_setup_pin_af(PPM_GPIO_PORT, PPM_GPIO_PIN, PPM_GPIO_AF, FALSE);
/* Time Base configuration */
rcc_periph_reset_pulse(RST_TIM_PPM);
timer_set_mode(PPM_TIMER, TIM_CR1_CKD_CK_INT,
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_set_period(PPM_TIMER, 0xFFFF);
uint32_t timer_clk = timer_get_frequency(PPM_TIMER);
timer_set_prescaler(PPM_TIMER, (timer_clk / (RC_PPM_TICKS_PER_USEC * ONE_MHZ_CLK)) - 1);
/* TIM configuration: Input Capture mode ---------------------
The Rising edge is used as active edge
------------------------------------------------------------ */
#if defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_POSITIVE
timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_RISING);
#elif defined PPM_PULSE_TYPE && PPM_PULSE_TYPE == PPM_PULSE_TYPE_NEGATIVE
timer_ic_set_polarity(PPM_TIMER, PPM_CHANNEL, TIM_IC_FALLING);
#else
#error "Unknown PPM_PULSE_TYPE"
#endif
timer_ic_set_input(PPM_TIMER, PPM_CHANNEL, PPM_TIMER_INPUT);
timer_ic_set_prescaler(PPM_TIMER, PPM_CHANNEL, TIM_IC_PSC_OFF);
timer_ic_set_filter(PPM_TIMER, PPM_CHANNEL, TIM_IC_OFF);
/* Enable timer Interrupt(s). */
nvic_set_priority(PPM_IRQ, PPM_IRQ_PRIO);
nvic_enable_irq(PPM_IRQ);
#ifdef PPM_IRQ2
nvic_set_priority(PPM_IRQ2, PPM_IRQ_PRIO);
nvic_enable_irq(PPM_IRQ2);
#endif
/* Enable the Capture/Compare and Update interrupt requests. */
timer_enable_irq(PPM_TIMER, (PPM_CC_IE | TIM_DIER_UIE));
/* Enable capture channel. */
timer_ic_enable(PPM_TIMER, PPM_CHANNEL);
/* TIM enable counter */
timer_enable_counter(PPM_TIMER);
timer_rollover_cnt = 0;
}
#if USE_PPM_TIM2
void tim2_isr(void)
{
if ((TIM2_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM2, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM2) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM2_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM2, TIM_SR_UIF);
}
}
#elif USE_PPM_TIM3
void tim3_isr(void)
{
if ((TIM3_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM3, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM3) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM3_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM3, TIM_SR_UIF);
}
}
#elif USE_PPM_TIM4
void tim4_isr(void)
{
if ((TIM4_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM4, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM4) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM4_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM4, TIM_SR_UIF);
}
}
#elif USE_PPM_TIM5
void tim5_isr(void)
{
if ((TIM5_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM5, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM5) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM5_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM5, TIM_SR_UIF);
}
}
#elif USE_PPM_TIM1
#if defined(STM32F1)
void tim1_up_isr(void)
{
#elif defined(STM32F4)
void tim1_up_tim10_isr(void) {
#endif
if ((TIM1_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM1, TIM_SR_UIF);
}
}
void tim1_cc_isr(void) {
if ((TIM1_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM1, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM1) + timer_rollover_cnt;
ppm_decode_frame(now);
}
}
#elif USE_PPM_TIM8
#if defined(STM32F1)
void tim8_up_isr(void) {
#elif defined(STM32F4)
void tim8_up_tim13_isr(void) {
#endif
if ((TIM8_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM8, TIM_SR_UIF);
}
}
void tim8_cc_isr(void) {
if ((TIM8_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM8, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM8) + timer_rollover_cnt;
ppm_decode_frame(now);
}
}
#elif USE_PPM_TIM9 && defined(STM32F4)
void tim1_brk_tim9_isr(void)
{
if ((TIM9_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM9, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM9) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM9_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM9, TIM_SR_UIF);
}
}
#elif USE_PPM_TIM12 && defined(STM32F4)
void tim8_brk_tim12_isr(void)
{
if ((TIM12_SR & PPM_CC_IF) != 0) {
timer_clear_flag(TIM12, PPM_CC_IF);
uint32_t now = timer_get_counter(TIM12) + timer_rollover_cnt;
ppm_decode_frame(now);
} else if ((TIM12_SR & TIM_SR_UIF) != 0) {
timer_rollover_cnt += (1 << 16);
timer_clear_flag(TIM12, TIM_SR_UIF);
}
}
#endif /* USE_PPM_TIM1 */

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2010-2014 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* @file arch/stm32/modules/radio_control/ppm_arch.h
* @ingroup stm32_arch
*
* STM32 ppm decoder.
*
*/
#ifndef PPM_ARCH_H
#define PPM_ARCH_H
/**
* The ppm counter is set-up to have 1/6 us resolution.
*
* The timer clock frequency (before prescaling):
* STM32F1:
* TIM1 -> APB2 = HCLK = 72MHz
* TIM2 -> 2 * APB1 = 2 * 36MHz = 72MHz
* STM32F4:
* TIM1 -> 2 * APB2 = 2 * 84MHz = 168MHz
* TIM2 -> 2 * APB1 = 2 * 42MHz = 84MHz
*/
#define RC_PPM_TICKS_PER_USEC 6
#define RC_PPM_TICKS_OF_USEC(_v) ((_v)*RC_PPM_TICKS_PER_USEC)
#define RC_PPM_SIGNED_TICKS_OF_USEC(_v) (int32_t)((_v)*RC_PPM_TICKS_PER_USEC)
#define USEC_OF_RC_PPM_TICKS(_v) ((_v)/RC_PPM_TICKS_PER_USEC)
#endif /* PPM_ARCH_H */

View File

@@ -1,63 +0,0 @@
#ifndef MY_DEBUG_SERVO_H
#define MY_DEBUG_SERVO_H
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
/* using servo 2 connector as debug */
#define DEBUG_S1_TOGGLE() { GPIOC_ODR ^= GPIO6; }
#define DEBUG_S1_ON() { GPIOC_BSRR = GPIO6; }
#define DEBUG_S1_OFF() { GPIOC_BRR = GPIO6; }
#define DEBUG_S2_TOGGLE() { GPIOC_ODR ^= GPIO7; }
#define DEBUG_S2_ON() { GPIOC_BSRR = GPIO7; }
#define DEBUG_S2_OFF() { GPIOC_BRR = GPIO7; }
#define DEBUG_S3_TOGGLE() { GPIOC_ODR ^= GPIO8; }
#define DEBUG_S3_ON() { GPIOC_BSRR = GPIO8; }
#define DEBUG_S3_OFF() { GPIOC_BRR = GPIO8; }
#define DEBUG_S4_TOGGLE() { GPIOC_ODR ^= GPIO9; }
#define DEBUG_S4_ON() { GPIOC_BSRR = GPIO9; }
#define DEBUG_S4_OFF() { GPIOC_BRR = GPIO9; }
#define DEBUG_S5_TOGGLE() { GPIOB_ODR ^= GPIO8; }
#define DEBUG_S5_ON() { GPIOB_BSRR = GPIO8; }
#define DEBUG_S5_OFF() { GPIOB_BRR = GPIO8; }
#define DEBUG_S6_TOGGLE() { GPIOB_ODR ^= GPIO9; }
#define DEBUG_S6_ON() { GPIOB_BSRR = GPIO9; }
#define DEBUG_S6_OFF() { GPIOB_BRR = GPIO9; }
#define DEBUG_SERVO1_INIT() { \
/* S1: PC6 S2: PC7 S3: PC8 */ \
GPIOC_BSRR = GPIO6 | GPIO7 | GPIO8 ; \
rcc_periph_clock_enable(RCC_GPIOC); \
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, GPIO6 | GPIO7 | GPIO8); \
DEBUG_S1_OFF(); \
DEBUG_S2_OFF(); \
DEBUG_S3_OFF(); \
}
#define DEBUG_SERVO2_INIT() { \
/* S4: PC9 */ \
GPIOC_BSRR = GPIO9; \
rcc_periph_clock_enable(RCC_GPIOC); \
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, GPIO9); \
/* S5: PB8 and S6: PB9 */ \
GPIOB_BSRR = GPIO8 | GPIO9; \
rcc_periph_clock_enable(RCC_GPIOB); \
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, \
GPIO_CNF_OUTPUT_PUSHPULL, GPIO8 | GPIO9); \
DEBUG_S4_OFF(); \
DEBUG_S5_OFF(); \
DEBUG_S6_OFF(); \
}
#endif /* MY_DEBUG_SERVO_H */

View File

@@ -1,36 +0,0 @@
/*
* Hey Emacs, this is a -*- makefile -*-
*
* Copyright (C) 2014 Freek van Tienen <freek.v.tienen@gmail.com>
*
* This file is part of Paparazzi.
*
* Paparazzi 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 2, or (at your option)
* any later version.
*
* Paparazzi 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 Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Linker script for Navstik (STM32F415, 1024K flash, 192K RAM). */
/* Define memory regions. */
MEMORY
{
/* only 128K (SRAM1 and SRAM2) are accessible by all AHB masters. */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
/* Reserving 128kb flash for persistent settings. */
rom (rx) : ORIGIN = 0x08000000, LENGTH = 896K
}
/* Include the common ld script. */
INCLUDE cortex-m-generic.ld

View File

@@ -1,62 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "peripherals/hmc5843.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/cm3/nvic.h>
#include "mcu_periph/i2c.h"
#ifndef STM32F1
#error "HMC5843 arch currently only implemented for STM32F1"
#endif
void hmc5843_arch_init(void)
{
/* configure external interrupt exti5 on PB5( mag int ) */
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_AFIO);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO5);
#ifdef HMC5843_USE_INT
exti_select_source(EXTI5, GPIOB);
exti_set_trigger(EXTI5, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI5);
nvic_set_priority(NVIC_EXTI9_5_IRQ, 0x0f);
nvic_enable_irq(NVIC_EXTI9_5_IRQ);
#endif
}
void hmc5843_arch_reset(void)
{
i2c2_er_irq_handler();
}
void exti9_5_isr(void)
{
exti_reset_request(EXTI5);
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef HMC5843_ARCH_H
#define HMC5843_ARCH_H
#include <libopencm3/stm32/gpio.h>
/* returns true if conversion done */
static inline int mag_eoc(void)
{
return (gpio_get(GPIOB, GPIO5) != 0);
}
#endif /* HMC5843_ARCH_H */

View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "peripherals/max1168.h"
#include "libopencm3/stm32/rcc.h"
#include "libopencm3/stm32/gpio.h"
#include "libopencm3/stm32/exti.h"
#include <libopencm3/cm3/nvic.h>
#ifndef STM32F1
#error "HMC5843 arch currently only implemented for STM32F1"
#endif
void max1168_arch_init(void)
{
/* configure external interrupt exti2 on PD2( data ready ) v1.0*/
/* PB2( data ready ) v1.1*/
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_AFIO);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO2);
exti_select_source(EXTI2, GPIOB);
exti_set_trigger(EXTI2, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI2);
nvic_set_priority(NVIC_EXTI2_IRQ, 0xF);
nvic_enable_irq(NVIC_EXTI2_IRQ);
}
void exti2_isr(void)
{
/* clear EXTI */
exti_reset_request(EXTI2);
max1168_status = MAX1168_GOT_EOC;
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef MAX1168_ARCH_H
#define MAX1168_ARCH_H
#endif /* MAX1168_ARCH_H */

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/peripherals/ms2100_arch.c
*
* STM32 specific functions for the ms2100 magnetic sensor from PNI.
*/
#include "peripherals/ms2100.h"
#include "mcu_periph/sys_time.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/cm3/nvic.h>
#ifndef STM32F1
#error "MS2100 arch currently only implemented for STM32F1"
#endif
void ms2100_arch_init(void)
{
/* set mag reset as output (reset on PC13) ----*/
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_AFIO);
gpio_set(GPIOC, GPIO13);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
Ms2100Reset();
/* configure data ready input on PB5 */
rcc_periph_clock_enable(RCC_GPIOB);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO5);
/* external interrupt for drdy pin */
exti_select_source(EXTI5, GPIOB);
exti_set_trigger(EXTI5, EXTI_TRIGGER_RISING);
exti_enable_request(EXTI5);
nvic_set_priority(NVIC_EXTI9_5_IRQ, 0x0f);
nvic_enable_irq(NVIC_EXTI9_5_IRQ);
}
void ms2100_reset_cb(struct spi_transaction *t __attribute__((unused)))
{
// set RESET pin high for at least 100 nsec
// busy wait should not harm
Ms2100Set();
// FIXME, make nanosleep funcion
uint32_t dt_ticks = cpu_ticks_of_nsec(110);
int32_t end_cpu_ticks = systick_get_value() - dt_ticks;
if (end_cpu_ticks < 0) {
end_cpu_ticks += systick_get_reload();
}
while (systick_get_value() > (uint32_t)end_cpu_ticks)
;
Ms2100Reset();
}
void exti9_5_isr(void)
{
ms2100.status = MS2100_GOT_EOC;
exti_reset_request(EXTI5);
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file arch/stm32/peripherals/ms2100_arch.h
*
* STM32 specific functions for the ms2100 magnetic sensor from PNI.
*/
#ifndef MS2100_ARCH_H
#define MS2100_ARCH_H
#include <libopencm3/stm32/gpio.h>
#include "mcu_periph/spi.h"
/**
* Here Reset indicates the Ms2100 is in normal state, i.e.
* the reset line is driven low (i.e. the GPIO is "reset")
*/
static inline void Ms2100Reset(void)
{
GPIOC_BRR = GPIO13;
}
/**
* Here Set indicates the Ms2100 is in reset state, i.e.
* the reset line is driven high (i.e. the GPIO is "set")
*/
static inline void Ms2100Set(void)
{
GPIOC_BSRR = GPIO13;
}
#define Ms2100HasEOC() (gpio_get(GPIOB, GPIO5) != 0)
/** Reset callback.
* called before spi transaction and after slave select
*/
extern void ms2100_reset_cb(struct spi_transaction *t);
#endif /* MS2100_ARCH_H */

Some files were not shown because too many files have changed in this diff Show More