mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
Rebuild tree structure, add blink for STM32F042
This commit is contained in:
parent
ce21cb7e10
commit
71838ae0f1
2
F0/Readme.md
Normal file
2
F0/Readme.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Samples for STM32F042-nucleo and chinese STM32F030-based devboard
|
||||||
|
blink - simple LED blink
|
||||||
133
F0/blink/Makefile
Normal file
133
F0/blink/Makefile
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
BINARY = blink
|
||||||
|
BOOTPORT ?= /dev/ttyUSB0
|
||||||
|
BOOTSPEED ?= 115200
|
||||||
|
# change this linking script depending on particular MCU model,
|
||||||
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
|
LDSCRIPT = ld/stm32f042k.ld
|
||||||
|
LIBNAME = opencm3_stm32f0
|
||||||
|
DEFS = -DSTM32F0 -DSTM32F042x6 -DEBUG
|
||||||
|
|
||||||
|
OBJDIR = mk
|
||||||
|
INDEPENDENT_HEADERS=
|
||||||
|
|
||||||
|
FP_FLAGS ?= -msoft-float
|
||||||
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m0 $(FP_FLAGS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Executables
|
||||||
|
PREFIX ?= arm-none-eabi
|
||||||
|
|
||||||
|
RM := rm -f
|
||||||
|
RMDIR := rmdir
|
||||||
|
CC := $(PREFIX)-gcc
|
||||||
|
LD := $(PREFIX)-gcc
|
||||||
|
AR := $(PREFIX)-ar
|
||||||
|
AS := $(PREFIX)-as
|
||||||
|
OBJCOPY := $(PREFIX)-objcopy
|
||||||
|
OBJDUMP := $(PREFIX)-objdump
|
||||||
|
GDB := $(PREFIX)-gdb
|
||||||
|
STFLASH = $(shell which st-flash)
|
||||||
|
STBOOT = $(shell which stm32flash)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Source files
|
||||||
|
LDSCRIPT ?= $(BINARY).ld
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||||
|
|
||||||
|
ifeq ($(strip $(OPENCM3_DIR)),)
|
||||||
|
OPENCM3_DIR := /usr/local/arm-none-eabi
|
||||||
|
$(info Using $(OPENCM3_DIR) path to library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
||||||
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
||||||
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C flags
|
||||||
|
CFLAGS += -O2 -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
|
CFLAGS += -Wredundant-decls
|
||||||
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C & C++ preprocessor common flags
|
||||||
|
CPPFLAGS += -MD
|
||||||
|
CPPFLAGS += -Wall -Werror
|
||||||
|
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS += --static -nostartfiles
|
||||||
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
|
LDFLAGS += -Wl,-Map=$(*).map
|
||||||
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Used libraries
|
||||||
|
LDLIBS += -l$(LIBNAME)
|
||||||
|
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||||
|
|
||||||
|
.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
|
BIN := $(BINARY).bin
|
||||||
|
HEX := $(BINARY).hex
|
||||||
|
|
||||||
|
all: list bin
|
||||||
|
|
||||||
|
elf: $(ELF)
|
||||||
|
bin: $(BIN)
|
||||||
|
hex: $(HEX)
|
||||||
|
list: $(LIST)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@printf " CC $<\n"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
%.h: ;
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@printf " OBJCOPY $(BIN)\n"
|
||||||
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|
||||||
|
$(HEX): $(ELF)
|
||||||
|
@printf " OBJCOPY $(HEX)\n"
|
||||||
|
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||||
|
|
||||||
|
$(LIST): $(ELF)
|
||||||
|
@printf " OBJDUMP $(LIST)\n"
|
||||||
|
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
|
||||||
|
@printf " LD $(ELF)\n"
|
||||||
|
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf " CLEAN\n"
|
||||||
|
$(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||||
|
$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
flash: $(BIN)
|
||||||
|
@printf " FLASH $(BIN)\n"
|
||||||
|
$(STFLASH) write $(BIN) 0x8000000
|
||||||
|
|
||||||
|
boot: $(BIN)
|
||||||
|
@printf " LOAD $(BIN) through bootloader\n"
|
||||||
|
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||||
|
|
||||||
|
.PHONY: clean elf hex list flash boot
|
||||||
|
|
||||||
|
#-include $(OBJS:.o=.d)
|
||||||
BIN
F0/blink/blink.bin
Executable file
BIN
F0/blink/blink.bin
Executable file
Binary file not shown.
31
F0/blink/ld/stm32f042k.ld
Normal file
31
F0/blink/ld/stm32f042k.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f0.ld
|
||||||
|
|
||||||
63
F0/blink/stm32f0.h
Normal file
63
F0/blink/stm32f0.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* stm32f0.h
|
||||||
|
*
|
||||||
|
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#include <libopencm3/stm32/rcc.h>
|
||||||
|
#include <libopencm3/stm32/flash.h>
|
||||||
|
|
||||||
|
#define RCC_CFGR_PLLXTPRE_HSE_CLK 0x0
|
||||||
|
#define RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2 0x1
|
||||||
|
#define RCC_CFGR_PLLSRC_HSI_CLK_DIV2 0x0
|
||||||
|
#define RCC_CFGR_PLLSRC_HSE_CLK 0x1
|
||||||
|
|
||||||
|
|
||||||
|
inline void rcc_clock_setup_in_hse_8mhz_out_48mhz(void){
|
||||||
|
RCC_CR |= RCC_CR_HSEON;
|
||||||
|
while ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSE;
|
||||||
|
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_HPRE) | RCC_CFGR_HPRE_NODIV;
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE) | RCC_CFGR_PPRE_NODIV;
|
||||||
|
|
||||||
|
FLASH_ACR = (FLASH_ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_024_048MHZ;
|
||||||
|
|
||||||
|
/* PLL: 8MHz * 6 = 48MHz */
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLMUL) | RCC_CFGR_PLLMUL_MUL6;
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLSRC) | (RCC_CFGR_PLLSRC_HSE_CLK << 16);
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLXTPRE) | (RCC_CFGR_PLLXTPRE_HSE_CLK << 17);
|
||||||
|
|
||||||
|
RCC_CR |= RCC_CR_PLLON;
|
||||||
|
while ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
|
||||||
|
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pin_toggle(uint32_t gpioport, uint16_t gpios){
|
||||||
|
uint32_t port = GPIO_ODR(gpioport);
|
||||||
|
GPIO_BSRR(gpioport) = ((port & gpios) << 16) | (~port & gpios);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pin_set(uint32_t gpioport, uint16_t gpios){GPIO_BSRR(gpioport) = gpios;}
|
||||||
|
inline void pin_clear(uint32_t gpioport, uint16_t gpios){GPIO_BSRR(gpioport) = (gpios << 16);}
|
||||||
|
inline int pin_read(uint32_t gpioport, uint16_t gpios){return GPIO_IDR(gpioport) & gpios ? 1 : 0;}
|
||||||
|
inline void pin_write(uint32_t gpioport, uint16_t gpios){GPIO_ODR(gpioport) = gpios;}
|
||||||
|
|
||||||
|
//#define do{}while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
82
F0/blink/systick_blink.c
Normal file
82
F0/blink/systick_blink.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Chuck McManis <cmcmanis@mcmanis.com>
|
||||||
|
* Copyright (C) 2013 Onno Kortmann <onno@gmx.net>
|
||||||
|
* Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz> (merge)
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libopencm3/stm32/rcc.h>
|
||||||
|
#include <libopencm3/stm32/gpio.h>
|
||||||
|
#include <libopencm3/cm3/nvic.h>
|
||||||
|
#include <libopencm3/cm3/systick.h>
|
||||||
|
|
||||||
|
#include "stm32f0.h"
|
||||||
|
|
||||||
|
/* Called when systick fires */
|
||||||
|
void sys_tick_handler(void){
|
||||||
|
pin_toggle(GPIOB, GPIO3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up timer to fire every x milliseconds
|
||||||
|
* This is a unusual usage of systick, be very careful with the 24bit range
|
||||||
|
* of the systick counter! You can range from 1 to 2796ms with this.
|
||||||
|
*/
|
||||||
|
static void systick_setup(int xms){
|
||||||
|
static int curms = 0;
|
||||||
|
if(curms == xms) return;
|
||||||
|
// 6MHz
|
||||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_EXT);
|
||||||
|
/* clear counter so it starts right away */
|
||||||
|
STK_CVR = 0;
|
||||||
|
|
||||||
|
systick_set_reload(6000 * xms);
|
||||||
|
systick_counter_enable();
|
||||||
|
systick_interrupt_enable();
|
||||||
|
curms = xms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set STM32 to clock by 48MHz from HSI oscillator */
|
||||||
|
static void clock_setup(void){
|
||||||
|
rcc_clock_setup_in_hsi_out_48mhz();
|
||||||
|
//rcc_clock_setup_in_hse_8mhz_out_48mhz();
|
||||||
|
|
||||||
|
/* Enable clocks to the GPIO subsystems (A&B) */
|
||||||
|
RCC_AHBENR = RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gpio_setup(void){
|
||||||
|
/* Set green led (PB3) as output */
|
||||||
|
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
|
||||||
|
/* D2 - PA12 - switch blink rate (pullup input) */
|
||||||
|
gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO12);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
clock_setup();
|
||||||
|
gpio_setup();
|
||||||
|
|
||||||
|
/* 500ms ticks => 1000ms period => 1Hz blinks */
|
||||||
|
systick_setup(500);
|
||||||
|
|
||||||
|
/* Do nothing in main loop */
|
||||||
|
while (1){
|
||||||
|
if(pin_read(GPIOA, GPIO12)) systick_setup(125); // no jumper - 4Hz
|
||||||
|
else systick_setup(500); // 1Hz
|
||||||
|
}
|
||||||
|
}
|
||||||
133
F1/1_wire/Makefile
Normal file
133
F1/1_wire/Makefile
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
BINARY = onewire
|
||||||
|
BOOTPORT ?= /dev/ttyUSB0
|
||||||
|
BOOTSPEED ?= 115200
|
||||||
|
# change this linking script depending on particular MCU model,
|
||||||
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
|
LDSCRIPT = ld/stm32f103xB.ld
|
||||||
|
LIBNAME = opencm3_stm32f1
|
||||||
|
DEFS = -DSTM32F1 -DEBUG
|
||||||
|
|
||||||
|
OBJDIR = mk
|
||||||
|
INDEPENDENT_HEADERS=
|
||||||
|
|
||||||
|
FP_FLAGS ?= -msoft-float
|
||||||
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Executables
|
||||||
|
PREFIX ?= arm-none-eabi
|
||||||
|
|
||||||
|
RM := rm -f
|
||||||
|
RMDIR := rmdir
|
||||||
|
CC := $(PREFIX)-gcc
|
||||||
|
LD := $(PREFIX)-gcc
|
||||||
|
AR := $(PREFIX)-ar
|
||||||
|
AS := $(PREFIX)-as
|
||||||
|
OBJCOPY := $(PREFIX)-objcopy
|
||||||
|
OBJDUMP := $(PREFIX)-objdump
|
||||||
|
GDB := $(PREFIX)-gdb
|
||||||
|
STFLASH = $(shell which st-flash)
|
||||||
|
STBOOT = $(shell which stm32flash)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Source files
|
||||||
|
LDSCRIPT ?= $(BINARY).ld
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||||
|
|
||||||
|
ifeq ($(strip $(OPENCM3_DIR)),)
|
||||||
|
OPENCM3_DIR := /usr/local/arm-none-eabi
|
||||||
|
$(info Using $(OPENCM3_DIR) path to library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
||||||
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
||||||
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C flags
|
||||||
|
CFLAGS += -Os -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
|
CFLAGS += -Wredundant-decls
|
||||||
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C & C++ preprocessor common flags
|
||||||
|
CPPFLAGS += -MD
|
||||||
|
CPPFLAGS += -Wall -Werror
|
||||||
|
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS += --static -nostartfiles
|
||||||
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
|
LDFLAGS += -Wl,-Map=$(*).map
|
||||||
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Used libraries
|
||||||
|
LDLIBS += -l$(LIBNAME)
|
||||||
|
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||||
|
|
||||||
|
.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
|
BIN := $(BINARY).bin
|
||||||
|
HEX := $(BINARY).hex
|
||||||
|
|
||||||
|
all: bin
|
||||||
|
|
||||||
|
elf: $(ELF)
|
||||||
|
bin: $(BIN)
|
||||||
|
hex: $(HEX)
|
||||||
|
list: $(LIST)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@printf " CC $<\n"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
%.h: ;
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@printf " OBJCOPY $(BIN)\n"
|
||||||
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|
||||||
|
$(HEX): $(ELF)
|
||||||
|
@printf " OBJCOPY $(HEX)\n"
|
||||||
|
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||||
|
|
||||||
|
$(LIST): $(ELF)
|
||||||
|
@printf " OBJDUMP $(LIST)\n"
|
||||||
|
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
|
||||||
|
@printf " LD $(ELF)\n"
|
||||||
|
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf " CLEAN\n"
|
||||||
|
$(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||||
|
$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
flash: $(BIN)
|
||||||
|
@printf " FLASH $(BIN)\n"
|
||||||
|
$(STFLASH) write $(BIN) 0x8000000
|
||||||
|
|
||||||
|
boot: $(BIN)
|
||||||
|
@printf " LOAD $(BIN) through bootloader\n"
|
||||||
|
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||||
|
|
||||||
|
.PHONY: clean elf hex list flash boot
|
||||||
|
|
||||||
|
#-include $(OBJS:.o=.d)
|
||||||
8
F1/1_wire/README
Normal file
8
F1/1_wire/README
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
My approach to semi-hardware 1-wire realisation based on DMA+TIM2
|
||||||
|
|
||||||
|
written for chinese devboard based on STM32F103RBT6
|
||||||
|
|
||||||
|
Press H for help
|
||||||
|
|
||||||
|
// Still some troubles left: for example, can't read ROM; also the code isn't fully done yet
|
||||||
|
|
||||||
314
F1/1_wire/cdcacm.c
Normal file
314
F1/1_wire/cdcacm.c
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
// Buffer for USB Tx
|
||||||
|
static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE];
|
||||||
|
static uint8_t USB_Tx_ptr = 0;
|
||||||
|
// connection flag
|
||||||
|
uint8_t USB_connected = 0;
|
||||||
|
static const struct usb_device_descriptor dev = {
|
||||||
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
.bDeviceClass = USB_CLASS_CDC,
|
||||||
|
.bDeviceSubClass = 0,
|
||||||
|
.bDeviceProtocol = 0,
|
||||||
|
.bMaxPacketSize0 = 64,
|
||||||
|
.idVendor = 0x0483,
|
||||||
|
.idProduct = 0x5740,
|
||||||
|
.bcdDevice = 0x0200,
|
||||||
|
.iManufacturer = 1,
|
||||||
|
.iProduct = 2,
|
||||||
|
.iSerialNumber = 3,
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
char usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data
|
||||||
|
int usbdatalen = 0; // lenght of received data
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This notification endpoint isn't implemented. According to CDC spec its
|
||||||
|
* optional, but its absence causes a NULL pointer dereference in Linux
|
||||||
|
* cdc_acm driver.
|
||||||
|
*/
|
||||||
|
static const struct usb_endpoint_descriptor comm_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x83,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
|
.wMaxPacketSize = 16,
|
||||||
|
.bInterval = 255,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_endpoint_descriptor data_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x01,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}, {
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x82,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
struct usb_cdc_header_descriptor header;
|
||||||
|
struct usb_cdc_call_management_descriptor call_mgmt;
|
||||||
|
struct usb_cdc_acm_descriptor acm;
|
||||||
|
struct usb_cdc_union_descriptor cdc_union;
|
||||||
|
} __attribute__((packed)) cdcacm_functional_descriptors = {
|
||||||
|
.header = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
|
||||||
|
.bcdCDC = 0x0110,
|
||||||
|
},
|
||||||
|
.call_mgmt = {
|
||||||
|
.bFunctionLength =
|
||||||
|
sizeof(struct usb_cdc_call_management_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
.bDataInterface = 1,
|
||||||
|
},
|
||||||
|
.acm = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
},
|
||||||
|
.cdc_union = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||||
|
.bControlInterface = 0,
|
||||||
|
.bSubordinateInterface0 = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor comm_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 0,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = comm_endp,
|
||||||
|
|
||||||
|
.extra = &cdcacm_functional_descriptors,
|
||||||
|
.extralen = sizeof(cdcacm_functional_descriptors),
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor data_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 2,
|
||||||
|
.bInterfaceClass = USB_CLASS_DATA,
|
||||||
|
.bInterfaceSubClass = 0,
|
||||||
|
.bInterfaceProtocol = 0,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = data_endp,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface ifaces[] = {{
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = comm_iface,
|
||||||
|
}, {
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = data_iface,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_config_descriptor config = {
|
||||||
|
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||||
|
.wTotalLength = 0,
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = 1,
|
||||||
|
.iConfiguration = 0,
|
||||||
|
.bmAttributes = 0x80,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
|
||||||
|
.interface = ifaces,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *usb_strings[] = {
|
||||||
|
"Organisation, author",
|
||||||
|
"device",
|
||||||
|
"version",
|
||||||
|
};
|
||||||
|
|
||||||
|
// default line coding: B115200, 1stop, 8bits, parity none
|
||||||
|
struct usb_cdc_line_coding linecoding = {
|
||||||
|
.dwDTERate = 115200,
|
||||||
|
.bCharFormat = USB_CDC_1_STOP_BITS,
|
||||||
|
.bParityType = USB_CDC_NO_PARITY,
|
||||||
|
.bDataBits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Buffer to be used for control requests. */
|
||||||
|
uint8_t usbd_control_buffer[128];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function runs every time it gets a request for control parameters get/set
|
||||||
|
* parameter SET_LINE_CODING used to change USART1 parameters: if you want to
|
||||||
|
* change them, just connect through USB with required parameters
|
||||||
|
*/
|
||||||
|
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
|
||||||
|
uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){
|
||||||
|
(void)complete;
|
||||||
|
(void)buf;
|
||||||
|
(void)usbd_dev;
|
||||||
|
char local_buf[10];
|
||||||
|
struct usb_cdc_line_coding lc;
|
||||||
|
|
||||||
|
switch (req->bRequest) {
|
||||||
|
case SET_CONTROL_LINE_STATE:{
|
||||||
|
if(req->wValue){ // terminal is opened
|
||||||
|
USB_connected = 1;
|
||||||
|
}else{ // terminal is closed
|
||||||
|
USB_connected = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This Linux cdc_acm driver requires this to be implemented
|
||||||
|
* even though it's optional in the CDC spec, and we don't
|
||||||
|
* advertise it in the ACM functional descriptor.
|
||||||
|
*/
|
||||||
|
struct usb_cdc_notification *notif = (void *)local_buf;
|
||||||
|
/* We echo signals back to host as notification. */
|
||||||
|
notif->bmRequestType = 0xA1;
|
||||||
|
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
|
||||||
|
notif->wValue = 0;
|
||||||
|
notif->wIndex = 0;
|
||||||
|
notif->wLength = 2;
|
||||||
|
local_buf[8] = req->wValue & 3;
|
||||||
|
local_buf[9] = 0;
|
||||||
|
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
|
||||||
|
}break;
|
||||||
|
case SET_LINE_CODING:
|
||||||
|
if (!len || (*len != sizeof(struct usb_cdc_line_coding)))
|
||||||
|
return 0;
|
||||||
|
memcpy((void *)&lc, (void *)*buf, *len);
|
||||||
|
// Mark & Space parity don't support by hardware, check it
|
||||||
|
if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){
|
||||||
|
return 0; // error
|
||||||
|
}else{
|
||||||
|
// memcpy((void *)&linecoding, (void *)&lc, sizeof(struct usb_cdc_line_coding));
|
||||||
|
// UART_setspeed(USART1, &linecoding);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_LINE_CODING: // return linecoding buffer
|
||||||
|
if(len && *len == sizeof(struct usb_cdc_line_coding))
|
||||||
|
memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding));
|
||||||
|
//usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen);
|
||||||
|
usbdatalen += len;
|
||||||
|
if(usbdatalen >= USB_RX_DATA_SIZE){ // buffer overflow - drop all its contents
|
||||||
|
usbdatalen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
|
||||||
|
{
|
||||||
|
(void)wValue;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
|
|
||||||
|
usbd_register_control_callback(
|
||||||
|
usbd_dev,
|
||||||
|
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||||
|
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||||
|
cdcacm_control_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbd_device *current_usb = NULL;
|
||||||
|
|
||||||
|
usbd_device *USB_init(){
|
||||||
|
current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config,
|
||||||
|
usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
if(!current_usb) return NULL;
|
||||||
|
usbd_register_set_config_callback(current_usb, cdcacm_set_config);
|
||||||
|
return current_usb;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_t send_block_mutex = MUTEX_UNLOCKED;
|
||||||
|
/**
|
||||||
|
* Put byte into USB buffer to send
|
||||||
|
* @param byte - a byte to put into a buffer
|
||||||
|
*/
|
||||||
|
void usb_send(uint8_t byte){
|
||||||
|
mutex_lock(&send_block_mutex);
|
||||||
|
USB_Tx_Buffer[USB_Tx_ptr++] = byte;
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it!
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send all data in buffer over USB
|
||||||
|
* this function runs when buffer is full or on SysTick
|
||||||
|
*/
|
||||||
|
void usb_send_buffer(){
|
||||||
|
if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return;
|
||||||
|
if(USB_Tx_ptr){
|
||||||
|
if(current_usb && USB_connected){
|
||||||
|
// usbd_ep_write_packet return 0 if previous packet isn't transmit yet
|
||||||
|
while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr));
|
||||||
|
usbd_poll(current_usb);
|
||||||
|
}
|
||||||
|
USB_Tx_ptr = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
}
|
||||||
54
F1/1_wire/cdcacm.h
Normal file
54
F1/1_wire/cdcacm.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ccdcacm.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __CCDCACM_H__
|
||||||
|
#define __CCDCACM_H__
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
|
// commands through EP0
|
||||||
|
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define GET_ENCAPSULATED_RESPONSE 0x01
|
||||||
|
#define SET_COMM_FEATURE 0x02
|
||||||
|
#define GET_COMM_FEATURE 0x03
|
||||||
|
#define CLEAR_COMM_FEATURE 0x04
|
||||||
|
#define SET_LINE_CODING 0x20
|
||||||
|
#define GET_LINE_CODING 0x21
|
||||||
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define SEND_BREAK 0x23
|
||||||
|
|
||||||
|
// Size of input/output buffers
|
||||||
|
#define USB_TX_DATA_SIZE 64
|
||||||
|
#define USB_RX_DATA_SIZE 64
|
||||||
|
|
||||||
|
// USB connection flag
|
||||||
|
extern uint8_t USB_connected;
|
||||||
|
extern struct usb_cdc_line_coding linecoding;
|
||||||
|
|
||||||
|
extern char usbdatabuf[];
|
||||||
|
extern int usbdatalen;
|
||||||
|
|
||||||
|
usbd_device *USB_init();
|
||||||
|
void usb_send(uint8_t byte);
|
||||||
|
void usb_send_buffer();
|
||||||
|
|
||||||
|
#endif // __CCDCACM_H__
|
||||||
98
F1/1_wire/hardware_ini.c
Normal file
98
F1/1_wire/hardware_ini.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.c - functions for HW initialisation
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All hardware-dependent initialisation & definition should be placed here
|
||||||
|
* and in hardware_ini.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO initialisaion: clocking + pins setup
|
||||||
|
*/
|
||||||
|
void GPIO_init(){
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
|
||||||
|
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN |
|
||||||
|
RCC_APB2ENR_IOPEEN);
|
||||||
|
// Buttons: pull-up input
|
||||||
|
gpio_set_mode(BTNS_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
|
||||||
|
BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// turn on pull-up
|
||||||
|
gpio_set(BTNS_PORT, BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// LEDS: opendrain output
|
||||||
|
gpio_set_mode(LEDS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
|
||||||
|
LED_D1_PIN | LED_D2_PIN);
|
||||||
|
// turn off LEDs
|
||||||
|
gpio_set(LEDS_PORT, LED_D1_PIN | LED_D2_PIN);
|
||||||
|
// test pin PC10: Push-Pull
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO10);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
// USB_DISC: push-pull
|
||||||
|
gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ,
|
||||||
|
GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN);
|
||||||
|
// USB_POWER: open drain, externall pull down with R7 (22k)
|
||||||
|
gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT,
|
||||||
|
GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SysTick used for system timer with period of 1ms
|
||||||
|
*/
|
||||||
|
void SysTick_init(){
|
||||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
||||||
|
systick_set_reload(8999); // 9000 pulses: 1kHz
|
||||||
|
systick_interrupt_enable();
|
||||||
|
systick_counter_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check buttons S2/S3
|
||||||
|
void check_btns(){
|
||||||
|
static uint8_t oldstate[2] = {1,1}; // old buttons state
|
||||||
|
uint8_t newstate[2], i;
|
||||||
|
static uint32_t Old_timer[2] = {0,0};
|
||||||
|
newstate[0] = gpio_get(BTNS_PORT, BTN_S2_PIN) ? 1 : 0;
|
||||||
|
newstate[1] = gpio_get(BTNS_PORT, BTN_S3_PIN) ? 1 : 0;
|
||||||
|
for(i = 0; i < 2; i++){
|
||||||
|
uint8_t new = newstate[i];
|
||||||
|
// pause for 60ms
|
||||||
|
uint32_t O = Old_timer[i];
|
||||||
|
if(O){
|
||||||
|
if(Timer - O > 60 || O > Timer){
|
||||||
|
P("Button S");
|
||||||
|
usb_send('2' + i);
|
||||||
|
if(new) P("released");
|
||||||
|
else P("pressed");
|
||||||
|
newline();
|
||||||
|
oldstate[i] = new;
|
||||||
|
Old_timer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(new != oldstate[i]){
|
||||||
|
Old_timer[i] = Timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
F1/1_wire/hardware_ini.h
Normal file
76
F1/1_wire/hardware_ini.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __HARDWARE_INI_H__
|
||||||
|
#define __HARDWARE_INI_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timers:
|
||||||
|
* SysTick - system time
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void GPIO_init();
|
||||||
|
void SysTick_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons on devboard
|
||||||
|
*/
|
||||||
|
#define BTNS_PORT GPIOC
|
||||||
|
// PCO -- S2
|
||||||
|
#define BTN_S2_PIN GPIO0
|
||||||
|
// PC1 -- S3
|
||||||
|
#define BTN_S3_PIN GPIO1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LEDS: PB9 for D1, PB8 for D2
|
||||||
|
*/
|
||||||
|
#define LEDS_PORT GPIOB
|
||||||
|
#define LED_D1_PIN GPIO9
|
||||||
|
#define LED_D2_PIN GPIO8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB interface
|
||||||
|
* connect boot1 jumper to gnd, boot0 to gnd; and reconnect boot0 to +3.3 to boot flash
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
// USB_DICS (disconnect) - PC11
|
||||||
|
#define USB_DISC_PIN GPIO11
|
||||||
|
#define USB_DISC_PORT GPIOC
|
||||||
|
// USB_POWER (high level when USB connected to PC)
|
||||||
|
#define USB_POWER_PIN GPIO10
|
||||||
|
#define USB_POWER_PORT GPIOC
|
||||||
|
// change signal level on USB diconnect pin
|
||||||
|
#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level
|
||||||
|
// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level
|
||||||
|
#define usb_disconnect() usb_disc_high()
|
||||||
|
#define usb_connect() usb_disc_low()
|
||||||
|
*/
|
||||||
|
// my simple devboard have no variants for programmed connection/disconnection of USB
|
||||||
|
#define usb_disconnect()
|
||||||
|
#define usb_connect()
|
||||||
|
|
||||||
|
void check_btns();
|
||||||
|
|
||||||
|
#endif // __HARDWARE_INI_H__
|
||||||
9
F1/1_wire/ld/devices.data
Normal file
9
F1/1_wire/ld/devices.data
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
stm32f103?4* stm32f1 ROM=16K RAM=6K
|
||||||
|
stm32f103?6* stm32f1 ROM=32K RAM=10K
|
||||||
|
stm32f103?8* stm32f1 ROM=64K RAM=20K
|
||||||
|
stm32f103?b* stm32f1 ROM=128K RAM=20K
|
||||||
|
stm32f103?c* stm32f1 ROM=256K RAM=48K
|
||||||
|
stm32f103?d* stm32f1 ROM=384K RAM=64K
|
||||||
|
stm32f103?e* stm32f1 ROM=512K RAM=64K
|
||||||
|
stm32f103?f* stm32f1 ROM=768K RAM=96K
|
||||||
|
stm32f103?g* stm32f1 ROM=1024K RAM=96K
|
||||||
31
F1/1_wire/ld/stm32f103x4.ld
Normal file
31
F1/1_wire/ld/stm32f103x4.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103x6.ld
Normal file
31
F1/1_wire/ld/stm32f103x6.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103x8.ld
Normal file
31
F1/1_wire/ld/stm32f103x8.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xB.ld
Normal file
31
F1/1_wire/ld/stm32f103xB.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xC.ld
Normal file
31
F1/1_wire/ld/stm32f103xC.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xD.ld
Normal file
31
F1/1_wire/ld/stm32f103xD.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xE.ld
Normal file
31
F1/1_wire/ld/stm32f103xE.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xF.ld
Normal file
31
F1/1_wire/ld/stm32f103xF.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/1_wire/ld/stm32f103xG.ld
Normal file
31
F1/1_wire/ld/stm32f103xG.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
92
F1/1_wire/main.c
Normal file
92
F1/1_wire/main.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "onewire.h"
|
||||||
|
|
||||||
|
volatile uint32_t Timer = 0; // global timer (milliseconds)
|
||||||
|
usbd_device *usbd_dev;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
uint32_t Old_timer = 0;
|
||||||
|
|
||||||
|
// RCC clocking: 8MHz oscillator -> 72MHz system
|
||||||
|
rcc_clock_setup_in_hse_8mhz_out_72mhz();
|
||||||
|
|
||||||
|
GPIO_init();
|
||||||
|
|
||||||
|
usb_disconnect(); // turn off USB while initializing all
|
||||||
|
|
||||||
|
// USB
|
||||||
|
usbd_dev = USB_init();
|
||||||
|
|
||||||
|
// SysTick is a system timer with 1ms period
|
||||||
|
SysTick_init();
|
||||||
|
|
||||||
|
// wait a little and then turn on USB pullup
|
||||||
|
// for (i = 0; i < 0x800000; i++)
|
||||||
|
// __asm__("nop");
|
||||||
|
|
||||||
|
usb_connect(); // turn on USB
|
||||||
|
|
||||||
|
init_ow_dmatimer();
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
if(usbdatalen){ // there's something in USB buffer
|
||||||
|
usbdatalen = parse_incoming_buf(usbdatabuf, usbdatalen);
|
||||||
|
}
|
||||||
|
//check_and_parse_UART(USART1); // also check data in UART buffers
|
||||||
|
check_btns();
|
||||||
|
if(Timer - Old_timer > 999){ // one-second cycle
|
||||||
|
Old_timer += 1000;
|
||||||
|
}else if(Timer < Old_timer){ // Timer overflow
|
||||||
|
Old_timer = 0;
|
||||||
|
}
|
||||||
|
OW_process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SysTick interrupt: increment global time & send data buffer through USB
|
||||||
|
*/
|
||||||
|
void sys_tick_handler(){
|
||||||
|
Timer++;
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pause function, delay in ms
|
||||||
|
void Delay(uint16_t _U_ time){
|
||||||
|
uint32_t waitto = Timer + time;
|
||||||
|
while(Timer < waitto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print current time in milliseconds: 4 bytes for ovrvlow + 4 bytes for time
|
||||||
|
* with ' ' as delimeter
|
||||||
|
*/
|
||||||
|
void print_time(){
|
||||||
|
print_int(Timer);
|
||||||
|
}
|
||||||
55
F1/1_wire/main.h
Normal file
55
F1/1_wire/main.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* main.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MAIN_H__
|
||||||
|
#define __MAIN_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
#include <libopencm3/stm32/gpio.h>
|
||||||
|
#include <libopencm3/stm32/usart.h>
|
||||||
|
#include <libopencm3/cm3/nvic.h>
|
||||||
|
#include <libopencm3/usb/cdc.h>
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
#include <libopencm3/cm3/systick.h>
|
||||||
|
#include <libopencm3/stm32/rcc.h>
|
||||||
|
#include <libopencm3/stm32/adc.h>
|
||||||
|
#include <libopencm3/stm32/dma.h>
|
||||||
|
#include <libopencm3/stm32/spi.h>
|
||||||
|
#include <libopencm3/stm32/timer.h>
|
||||||
|
|
||||||
|
#define ADC_CHANNELS_NUMBER (10)
|
||||||
|
|
||||||
|
#include "sync.h" // mutexes
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
#define _U_ __attribute__((__unused__))
|
||||||
|
#define U8(x) ((uint8_t) x)
|
||||||
|
#define U16(x) ((uint16_t) x)
|
||||||
|
#define U32(x) ((uint32_t) x)
|
||||||
|
|
||||||
|
extern volatile uint32_t Timer; // global timer (milliseconds)
|
||||||
|
void Delay(uint16_t time);
|
||||||
|
|
||||||
|
#endif // __MAIN_H__
|
||||||
|
|
||||||
BIN
F1/1_wire/onewire.bin
Executable file
BIN
F1/1_wire/onewire.bin
Executable file
Binary file not shown.
554
F1/1_wire/onewire.c
Normal file
554
F1/1_wire/onewire.c
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
/*
|
||||||
|
* onewire.c - functions to work with 1-wire devices
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#include "onewire.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
OW_ID id_array[OW_MAX_NUM]; // 1-wire devices ID buffer (not more than eight)
|
||||||
|
uint8_t dev_amount = 0; // amount of 1-wire devices
|
||||||
|
|
||||||
|
|
||||||
|
// states of 1-wire processing queue
|
||||||
|
typedef enum{
|
||||||
|
OW_OFF_STATE, // not working
|
||||||
|
OW_RESET_STATE, // reset bus
|
||||||
|
OW_SEND_STATE, // send data
|
||||||
|
OW_READ_STATE, // wait for reading
|
||||||
|
} OW_States;
|
||||||
|
volatile OW_States OW_State = OW_OFF_STATE; // 1-wire state, 0-not runned
|
||||||
|
|
||||||
|
void (*ow_process_resdata)() = NULL;
|
||||||
|
void wait_reading();
|
||||||
|
|
||||||
|
uint16_t tim2_buff[TIM2_DMABUFF_SIZE];
|
||||||
|
uint16_t tim2_inbuff[TIM2_DMABUFF_SIZE];
|
||||||
|
int tum2buff_ctr = 0;
|
||||||
|
uint8_t ow_done = 1;
|
||||||
|
uint8_t ow_measurements_done = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function sends bits of ow_byte (LSB first) to 1-wire line
|
||||||
|
* @param ow_byte - byte to convert
|
||||||
|
* @param Nbits - number of bits to send
|
||||||
|
* @param ini - 1 to zero counter
|
||||||
|
*/
|
||||||
|
uint8_t OW_add_byte(uint8_t ow_byte){
|
||||||
|
uint8_t i, byte;
|
||||||
|
for(i = 0; i < 8; i++){
|
||||||
|
if(ow_byte & 0x01){
|
||||||
|
byte = BIT_ONE_P;
|
||||||
|
}else{
|
||||||
|
byte = BIT_ZERO_P;
|
||||||
|
}
|
||||||
|
if(tum2buff_ctr == TIM2_DMABUFF_SIZE){
|
||||||
|
ERR("Tim2 buffer overflow");
|
||||||
|
return 0; // avoid buffer overflow
|
||||||
|
}
|
||||||
|
tim2_buff[tum2buff_ctr++] = byte;
|
||||||
|
ow_byte >>= 1;
|
||||||
|
}
|
||||||
|
// INT(tum2buff_ctr);
|
||||||
|
// DBG(" bytes in send buffer\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds Nbytes bytes 0xff for reading sequence
|
||||||
|
*/
|
||||||
|
uint8_t OW_add_read_seq(uint8_t Nbytes){
|
||||||
|
uint8_t i;
|
||||||
|
if(Nbytes == 0) return 0;
|
||||||
|
Nbytes *= 8; // 8 bits for each byte
|
||||||
|
for(i = 0; i < Nbytes; i++){
|
||||||
|
if(tum2buff_ctr == TIM2_DMABUFF_SIZE){
|
||||||
|
ERR("Tim2 buffer overflow");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tim2_buff[tum2buff_ctr++] = BIT_READ_P;
|
||||||
|
}
|
||||||
|
// INT(tum2buff_ctr);
|
||||||
|
// DBG(" bytes in send buffer\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill output buffer with data from 1-wire
|
||||||
|
* @param start_idx - index from which to start (byte number)
|
||||||
|
* @param N - data length (in **bytes**)
|
||||||
|
* @outbuf - where to place data
|
||||||
|
*/
|
||||||
|
void read_from_OWbuf(uint8_t start_idx, uint8_t N, uint8_t *outbuf){
|
||||||
|
start_idx *= 8;
|
||||||
|
uint8_t i, j, last = start_idx + N * 8, byte;
|
||||||
|
if(last >= TIM2_DMABUFF_SIZE) last = TIM2_DMABUFF_SIZE;
|
||||||
|
for(i = start_idx; i < last;){
|
||||||
|
byte = 0;
|
||||||
|
for(j = 0; j < 8; j++){
|
||||||
|
byte >>= 1;
|
||||||
|
// INT(tim2_inbuff[i]);
|
||||||
|
// DBG(" ");
|
||||||
|
if(tim2_inbuff[i++] < ONE_ZERO_BARRIER)
|
||||||
|
byte |= 0x80;
|
||||||
|
}
|
||||||
|
*outbuf++ = byte;
|
||||||
|
// DBG("readed \n");
|
||||||
|
}
|
||||||
|
// print_hex(outbuf-N, N);
|
||||||
|
// DBG(" readed\n");
|
||||||
|
}
|
||||||
|
// there's a mistake in opencm3, so redefine this if needed (TIM_CCMR2_CC3S_IN_TI1 -> TIM_CCMR2_CC3S_IN_TI4)
|
||||||
|
#ifndef TIM_CCMR2_CC3S_IN_TI4
|
||||||
|
#define TIM_CCMR2_CC3S_IN_TI4 (2)
|
||||||
|
#endif
|
||||||
|
void init_ow_dmatimer(){ // tim2_ch4 - PA3, no remap
|
||||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
|
||||||
|
GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
|
||||||
|
rcc_periph_clock_enable(RCC_TIM2);
|
||||||
|
rcc_periph_clock_enable(RCC_DMA1);
|
||||||
|
timer_reset(TIM2);
|
||||||
|
// timers have frequency of 1MHz -- 1us for one step
|
||||||
|
// 36MHz of APB1
|
||||||
|
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
|
||||||
|
// 72MHz div 72 = 1MHz
|
||||||
|
TIM2_PSC = 71; // prescaler is (div - 1)
|
||||||
|
TIM2_CR1 = TIM_CR1_ARPE; // bufferize ARR/CCR
|
||||||
|
TIM2_ARR = RESET_LEN;
|
||||||
|
// PWM_OUT: TIM2_CH4; capture: TIM2_CH3
|
||||||
|
// PWM edge-aligned mode & enable preload for CCR4, CC3 takes input from TI4
|
||||||
|
TIM2_CCMR2 = TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE | TIM_CCMR2_CC3S_IN_TI4;
|
||||||
|
TIM2_CCR4 = 0; // set output value to 1 by clearing CCR4
|
||||||
|
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
|
||||||
|
// set low polarity for CC4, high for CC3 & enable CC4 out and CC3 in
|
||||||
|
TIM2_CCER = TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC3E;
|
||||||
|
|
||||||
|
// TIM2_CH4 - DMA1, channel 7
|
||||||
|
dma_channel_reset(DMA1, DMA_CHANNEL7);
|
||||||
|
DMA1_CCR7 = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
|
||||||
|
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
|
||||||
|
nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr
|
||||||
|
tum2buff_ctr = 0;
|
||||||
|
DBG("OW INITED\n");
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_set(GPIOC, GPIO10);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_dmatimer(){
|
||||||
|
ow_done = 0;
|
||||||
|
TIM2_CR1 = 0;
|
||||||
|
adc_disable_dma(ADC1); // turn off DMA & ADC
|
||||||
|
adc_off(ADC1);
|
||||||
|
// TIM2_CH4 - DMA1, channel 7
|
||||||
|
DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_GIF7 |
|
||||||
|
DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_GIF1; // clear flags
|
||||||
|
DMA1_CCR7 &= ~DMA_CCR_EN; // disable (what if it's enabled?) to set address
|
||||||
|
DMA1_CPAR7 = (uint32_t) &(TIM_CCR4(TIM2)); // dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
|
||||||
|
DMA1_CMAR7 = (uint32_t) &tim2_buff[1]; // dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);
|
||||||
|
DMA1_CNDTR7 = tum2buff_ctr-1;//dma_set_number_of_data(DMA1, DMA_CHANNEL7, tum2buff_ctr);
|
||||||
|
// TIM2_CH3 - DMA1, channel 1
|
||||||
|
dma_channel_reset(DMA1, DMA_CHANNEL1);
|
||||||
|
DMA1_CCR1 = DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
|
||||||
|
| DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_PL_HIGH;
|
||||||
|
DMA1_CPAR1 = (uint32_t) &(TIM_CCR3(TIM2)); //dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
|
||||||
|
DMA1_CMAR1 = (uint32_t) tim2_inbuff; //dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
|
||||||
|
DMA1_CNDTR1 = tum2buff_ctr; //dma_set_number_of_data(DMA1, DMA_CHANNEL1, tum2buff_ctr);
|
||||||
|
nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
|
||||||
|
|
||||||
|
DMA1_CCR7 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL7);
|
||||||
|
DMA1_CCR1 |= DMA_CCR_EN; //dma_enable_channel(DMA1, DMA_CHANNEL1);
|
||||||
|
|
||||||
|
TIM2_SR = 0; // clear all flags
|
||||||
|
TIM2_ARR = BIT_LEN; // bit length
|
||||||
|
TIM2_CCR4 = tim2_buff[0]; // we should manually set first bit to avoid zero in tim2_inbuff[0]
|
||||||
|
TIM2_EGR = TIM_EGR_UG; // update value of ARR
|
||||||
|
TIM2_CR1 = TIM_CR1_ARPE; // bufferize ARR/CCR
|
||||||
|
|
||||||
|
TIM2_CR2 &= ~TIM_CR2_CCDS; // timer_set_dma_on_compare_event(TIM2);
|
||||||
|
TIM2_DIER = TIM_DIER_CC4DE | TIM_DIER_CC3DE; // enable DMA events
|
||||||
|
// set low polarity, enable cc out & enable input capture
|
||||||
|
TIM2_CR1 |= TIM_CR1_CEN; // run timer
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_clear(GPIOC, GPIO10);
|
||||||
|
#endif
|
||||||
|
/* DBG("RUN transfer of ");
|
||||||
|
INT(tum2buff_ctr);
|
||||||
|
DBG(" bits\n");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t rstat = 0, lastcc3 = 3;
|
||||||
|
void ow_reset(){
|
||||||
|
//init_ow_dmatimer();
|
||||||
|
ow_done = 0;
|
||||||
|
rstat = 0;
|
||||||
|
TIM2_SR = 0; // clear all flags
|
||||||
|
TIM2_CR1 = 0;
|
||||||
|
TIM2_DIER = 0; // disable timer interrupts
|
||||||
|
TIM2_ARR = RESET_LEN; // set period to 1ms
|
||||||
|
TIM2_CCR4 = RESET_P; // zero pulse length
|
||||||
|
TIM2_EGR = TIM_EGR_UG; // update values of ARR & CCR4
|
||||||
|
//TIM2_CCMR2 = TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE | TIM_CCMR2_CC3S_IN_TI4;
|
||||||
|
//TIM2_CCER = TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC3E;
|
||||||
|
// DBG("OW RESET in process");
|
||||||
|
TIM2_DIER = TIM_DIER_CC3IE;
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_clear(GPIOC, GPIO10);
|
||||||
|
#endif
|
||||||
|
TIM2_CR1 = TIM_CR1_OPM | TIM_CR1_CEN | TIM_CR1_UDIS; // we need only single pulse & run timer; disable UEV
|
||||||
|
TIM2_SR = 0; // clear update flag generated after timer's running
|
||||||
|
nvic_enable_irq(NVIC_TIM2_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tim2_isr(){
|
||||||
|
if(TIM2_SR & TIM_SR_UIF){ // update interrupt
|
||||||
|
TIM2_DIER = 0; // disable all timer interrupts
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_set(GPIOC, GPIO10);
|
||||||
|
#endif
|
||||||
|
TIM2_CCR4 = 0; // set output value to 1
|
||||||
|
TIM2_SR = 0; // clear flag
|
||||||
|
nvic_disable_irq(NVIC_TIM2_IRQ);
|
||||||
|
ow_done = 1;
|
||||||
|
rstat = lastcc3;
|
||||||
|
// DBG(" ... done!\n");
|
||||||
|
}
|
||||||
|
if(TIM2_SR & TIM_SR_CC3IF){ // we need this interrupt to store CCR3 value
|
||||||
|
lastcc3 = TIM2_CCR3;
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_UDIS; // enable UEV
|
||||||
|
TIM2_SR = 0; // clear flag (we've manage TIM_SR_UIF before, so can simply do =0)
|
||||||
|
TIM2_DIER |= TIM_DIER_UIE; // Now allow also Update interrupts to turn off everything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DMA interrupt in 1-wire mode
|
||||||
|
*/
|
||||||
|
void dma1_channel1_isr(){
|
||||||
|
// int i;
|
||||||
|
if(DMA1_ISR & DMA_ISR_TCIF1){
|
||||||
|
#ifdef EBUG
|
||||||
|
gpio_set(GPIOC, GPIO10);
|
||||||
|
#endif
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTCIF1;
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_CEN; // timer_disable_counter(TIM2);
|
||||||
|
DMA1_CCR1 &= ~DMA_CCR_EN; // disable DMA1 channel 1
|
||||||
|
nvic_disable_irq(NVIC_DMA1_CHANNEL1_IRQ);
|
||||||
|
ow_done = 1;
|
||||||
|
/* for(i = 0; i < tum2buff_ctr; i++){
|
||||||
|
print_int(tim2_inbuff[i]);
|
||||||
|
P(" ");
|
||||||
|
}
|
||||||
|
P("\n");*/
|
||||||
|
}else if(DMA1_ISR & DMA_ISR_TEIF1){
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTEIF1;
|
||||||
|
DBG("DMA in transfer error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dma1_channel7_isr(){
|
||||||
|
if(DMA1_ISR & DMA_ISR_TCIF7){
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTCIF7; // clear flag
|
||||||
|
DMA1_CCR7 &= ~DMA_CCR_EN; // disable DMA1 channel 7
|
||||||
|
}else if(DMA1_ISR & DMA_ISR_TEIF7){
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTEIF7;
|
||||||
|
DBG("DMA out transfer error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t OW_get_reset_status(){
|
||||||
|
if(rstat < RESET_BARRIER) return 0; // no devices
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t ow_data_ready = 0; // flag of reading OK
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process 1-wire commands depending on its state
|
||||||
|
*/
|
||||||
|
void OW_process(){
|
||||||
|
static uint8_t ow_was_reseting = 0;
|
||||||
|
switch(OW_State){
|
||||||
|
case OW_OFF_STATE:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case OW_RESET_STATE:
|
||||||
|
//DBG("OW reset\n");
|
||||||
|
OW_State = OW_SEND_STATE;
|
||||||
|
ow_was_reseting = 1;
|
||||||
|
ow_reset();
|
||||||
|
break;
|
||||||
|
case OW_SEND_STATE:
|
||||||
|
if(!ow_done) return; // reset in work
|
||||||
|
if(ow_was_reseting){
|
||||||
|
if(rstat < RESET_BARRIER){
|
||||||
|
ERR("Error: no 1-wire devices found");
|
||||||
|
INT(rstat);
|
||||||
|
DBG("\n");
|
||||||
|
ow_was_reseting = 0;
|
||||||
|
OW_State = OW_OFF_STATE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ow_was_reseting = 0;
|
||||||
|
OW_State = OW_READ_STATE;
|
||||||
|
run_dmatimer(); // turn on data transfer
|
||||||
|
//DBG("OW send\n");
|
||||||
|
break;
|
||||||
|
case OW_READ_STATE:
|
||||||
|
if(!ow_done) return; // data isn't ready
|
||||||
|
OW_State = OW_OFF_STATE;
|
||||||
|
// adc_dma_on(); // return DMA1_1 to ADC at end of data transmitting
|
||||||
|
if(ow_process_resdata)
|
||||||
|
ow_process_resdata();
|
||||||
|
ow_data_ready = 1;
|
||||||
|
//DBG("OW read\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *read_buf = NULL; // buffer for storing readed data
|
||||||
|
/**
|
||||||
|
* fill ID buffer with readed data
|
||||||
|
*/
|
||||||
|
void fill_buff_with_data(){
|
||||||
|
ow_process_resdata = NULL;
|
||||||
|
if(!read_buf) return;
|
||||||
|
read_from_OWbuf(1, 8, read_buf);
|
||||||
|
int i, j;
|
||||||
|
P("Readed ID: ");
|
||||||
|
for(i = 0; i < 8; ++i){
|
||||||
|
print_hex(&read_buf[i], 1);
|
||||||
|
usb_send(' ');
|
||||||
|
}
|
||||||
|
usb_send('\n');
|
||||||
|
// now check stored ROMs
|
||||||
|
for(i = 0; i < dev_amount; ++i){
|
||||||
|
uint8_t *ROM = id_array[i].bytes;
|
||||||
|
for(j = 0; j < 8; j++)
|
||||||
|
if(ROM[j] != read_buf[j]) break;
|
||||||
|
if(j == 8){ // we found this cell
|
||||||
|
DBG("Such ID exists\n");
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++dev_amount;
|
||||||
|
ret:
|
||||||
|
read_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fill Nth array with identificators
|
||||||
|
*/
|
||||||
|
//uint8_t comtosend = 0;
|
||||||
|
void OW_fill_next_ID(){
|
||||||
|
if(dev_amount >= OW_MAX_NUM){
|
||||||
|
ERR("No memory left for new device\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ow_data_ready = 0;
|
||||||
|
OW_State = OW_RESET_STATE;
|
||||||
|
OW_reset_buffer();
|
||||||
|
OW_add_byte(OW_READ_ROM);
|
||||||
|
OW_add_read_seq(8); // wait for 8 bytes
|
||||||
|
read_buf = id_array[dev_amount].bytes;
|
||||||
|
ow_process_resdata = fill_buff_with_data;
|
||||||
|
DBG("wait for ID\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure of 1-wire communications
|
||||||
|
* variables:
|
||||||
|
* @param sendReset - send RESET before transmission
|
||||||
|
* @param command - bytes sent to the bus (if we want to read, send OW_READ_SLOT)
|
||||||
|
* @param cLen - command buffer length (how many bytes to send)
|
||||||
|
* @return 1 if succeed, 0 if failure
|
||||||
|
*/
|
||||||
|
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen){
|
||||||
|
ow_data_ready = 0;
|
||||||
|
// if reset needed - send RESET and check bus
|
||||||
|
if(sendReset)
|
||||||
|
OW_State = OW_RESET_STATE;
|
||||||
|
else
|
||||||
|
OW_State = OW_SEND_STATE;
|
||||||
|
OW_reset_buffer();
|
||||||
|
while(cLen-- > 0){
|
||||||
|
if(!OW_add_byte(*command++)) return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert temperature from scratchpad
|
||||||
|
* in case of error return 200000 (ERR_TEMP_VAL)
|
||||||
|
* return value in 10th degrees centigrade
|
||||||
|
*
|
||||||
|
* 0 - themperature LSB
|
||||||
|
* 1 - themperature MSB (all higher bits are sign)
|
||||||
|
* 2 - T_H
|
||||||
|
* 3 - T_L
|
||||||
|
* 4 - B20: Configuration register (only bits 6/5 valid: 9..12 bits resolution); 0xff for S20
|
||||||
|
* 5 - 0xff (reserved)
|
||||||
|
* 6 - (reserved for B20); S20: COUNT_REMAIN (0x0c)
|
||||||
|
* 7 - COUNT PER DEGR (0x10)
|
||||||
|
* 8 - CRC
|
||||||
|
*/
|
||||||
|
int32_t gettemp(uint8_t *scratchpad){
|
||||||
|
// detect DS18S20
|
||||||
|
int32_t t = 0;
|
||||||
|
uint8_t l,m;
|
||||||
|
int8_t v;
|
||||||
|
if(scratchpad[7] == 0xff) // 0xff can be only if there's no such device or some other error
|
||||||
|
return ERR_TEMP_VAL;
|
||||||
|
m = scratchpad[1];
|
||||||
|
l = scratchpad[0];
|
||||||
|
if(scratchpad[4] == 0xff){ // DS18S20
|
||||||
|
v = l >> 1 | (m & 0x80); // take signum from MSB
|
||||||
|
t = ((int32_t)v) * 10L;
|
||||||
|
if(l&1) t += 5L; // decimal 0.5
|
||||||
|
}else{ // DS18B20
|
||||||
|
v = l>>4 | ((m & 7)<<4) | (m & 0x80);
|
||||||
|
t = ((int32_t)v) * 10L;
|
||||||
|
m = (l & 0x0f) >> 1; // add decimal
|
||||||
|
// 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 ->
|
||||||
|
// 0 1 1 2 3 3 4 4 5 6 6 7 8 8 9 9
|
||||||
|
t += (int32_t)m; // t = v*10 + l*0.625 -> convert
|
||||||
|
if(m) ++t; // 1->1, 2->3, 3->4, 4->5, 5->6
|
||||||
|
if(m > 5) ++t; // 6->8, 7->9
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t temperature = ERR_TEMP_VAL;
|
||||||
|
int8_t Ncur = 0;
|
||||||
|
/**
|
||||||
|
* get temperature from buffer
|
||||||
|
*/
|
||||||
|
void convert_next_temp(){
|
||||||
|
uint8_t scratchpad[9];
|
||||||
|
ow_process_resdata = NULL;
|
||||||
|
if(dev_amount < 2){
|
||||||
|
read_from_OWbuf(2, 9, scratchpad);
|
||||||
|
}else{
|
||||||
|
read_from_OWbuf(10, 9, scratchpad);
|
||||||
|
}
|
||||||
|
temperature = gettemp(scratchpad);
|
||||||
|
DBG("Readed temperature: ");
|
||||||
|
INT(temperature);
|
||||||
|
DBG("/10 degrC\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read next stored thermometer
|
||||||
|
*/
|
||||||
|
void OW_read_next_temp(){
|
||||||
|
ow_data_ready = 0;
|
||||||
|
OW_State = OW_RESET_STATE;
|
||||||
|
OW_reset_buffer();
|
||||||
|
int i;
|
||||||
|
if(dev_amount < 2){
|
||||||
|
Ncur = -1;
|
||||||
|
OW_add_byte(OW_SKIP_ROM);
|
||||||
|
}else{
|
||||||
|
if(++Ncur >= dev_amount) Ncur = 0;
|
||||||
|
OW_add_byte(OW_MATCH_ROM);
|
||||||
|
uint8_t *ROM = id_array[Ncur].bytes;
|
||||||
|
for(i = 0; i < 8; ++i)
|
||||||
|
OW_add_byte(ROM[i]);
|
||||||
|
}
|
||||||
|
OW_add_byte(OW_READ_SCRATCHPAD);
|
||||||
|
OW_add_read_seq(9); // wait for 9 bytes - ROM
|
||||||
|
ow_process_resdata = convert_next_temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_reading(){
|
||||||
|
uint8_t bt;
|
||||||
|
read_from_OWbuf(0, 1, &bt);
|
||||||
|
if(bt == 0xff){ // the conversion is done!
|
||||||
|
ow_measurements_done = 1;
|
||||||
|
ow_process_resdata = NULL;
|
||||||
|
DBG("Measurements done!\n");
|
||||||
|
}else{
|
||||||
|
OW_State = OW_SEND_STATE;
|
||||||
|
OW_reset_buffer();
|
||||||
|
ow_data_ready = 0;
|
||||||
|
OW_add_read_seq(1); // send read seq waiting for end of conversion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OW_send_read_seq(){
|
||||||
|
ow_data_ready = 0;
|
||||||
|
ow_measurements_done = 0;
|
||||||
|
OW_State = OW_RESET_STATE;
|
||||||
|
OW_reset_buffer();
|
||||||
|
OW_add_byte(OW_SKIP_ROM);
|
||||||
|
OW_add_byte(OW_CONVERT_T);
|
||||||
|
OW_add_read_seq(1); // send read seq waiting for end of conversion
|
||||||
|
ow_process_resdata = wait_reading;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* scan 1-wire bus
|
||||||
|
* WARNING! The procedure works in real-time, so it is VERY LONG
|
||||||
|
* num - max number of devices
|
||||||
|
* buf - array for devices' ID's (8*num bytes)
|
||||||
|
* return amount of founded devices
|
||||||
|
*
|
||||||
|
uint8_t OW_Scan(uint8_t *buf, uint8_t num){
|
||||||
|
unsigned long path,next,pos;
|
||||||
|
uint8_t bit,chk;
|
||||||
|
uint8_t cnt_bit, cnt_byte, cnt_num;
|
||||||
|
path=0;
|
||||||
|
cnt_num=0;
|
||||||
|
do{
|
||||||
|
//(issue the 'ROM search' command)
|
||||||
|
if( 0 == OW_WriteCmd(OW_SEARCH_ROM) ) return 0;
|
||||||
|
OW_Wait_TX();
|
||||||
|
OW_ClearBuff(); // clear RX buffer
|
||||||
|
next = 0; // next path to follow
|
||||||
|
pos = 1; // path bit pointer
|
||||||
|
for(cnt_byte = 0; cnt_byte != 8; cnt_byte++){
|
||||||
|
buf[cnt_num*8 + cnt_byte] = 0;
|
||||||
|
for(cnt_bit = 0; cnt_bit != 8; cnt_bit++){
|
||||||
|
//(read two bits, 'bit' and 'chk', from the 1-wire bus)
|
||||||
|
OW_SendBits(OW_R, 2);
|
||||||
|
OW_Wait_TX();
|
||||||
|
bit = -----OW_ReadByte();
|
||||||
|
chk = bit & 0x02; // bit 1
|
||||||
|
bit = bit & 0x01; // bit 0
|
||||||
|
if(bit && chk) return 0; // error
|
||||||
|
if(!bit && !chk){ // collision, both are zero
|
||||||
|
if (pos & path) bit = 1; // if we've been here before
|
||||||
|
else next = (path&(pos-1)) | pos; // else, new branch for next
|
||||||
|
pos <<= 1;
|
||||||
|
}
|
||||||
|
//(save this bit as part of the current ROM value)
|
||||||
|
if (bit) buf[cnt_num*8 + cnt_byte]|=(1<<cnt_bit);
|
||||||
|
//(write 'bit' to the 1-wire bus)
|
||||||
|
OW_SendBits(bit, 1);
|
||||||
|
OW_Wait_TX();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path=next;
|
||||||
|
cnt_num++;
|
||||||
|
}while(path && cnt_num < num);
|
||||||
|
return cnt_num;
|
||||||
|
}*/
|
||||||
|
|
||||||
140
F1/1_wire/onewire.h
Normal file
140
F1/1_wire/onewire.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* onewire.h
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __ONEWIRE_H__
|
||||||
|
#define __ONEWIRE_H__
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
// 20 bytes x 8bits
|
||||||
|
#define TIM2_DMABUFF_SIZE 160
|
||||||
|
|
||||||
|
// freq = 1MHz
|
||||||
|
// ARR values: 1000 for reset, 100 for data in/out
|
||||||
|
// CCR4 values: 500 for reset, 60 for sending 0 or reading, <15 for sending 1
|
||||||
|
// CCR3 values: >550 if there's devices on line (on reset), >12 (typ.15) - read 0, < 12 (typ.1) - read 1
|
||||||
|
#define RESET_LEN ((uint16_t)1000)
|
||||||
|
#define BIT_LEN ((uint16_t)100)
|
||||||
|
#define RESET_P ((uint16_t)500)
|
||||||
|
#define BIT_ONE_P ((uint16_t)10)
|
||||||
|
#define BIT_ZERO_P ((uint16_t)60)
|
||||||
|
#define BIT_READ_P ((uint16_t)5)
|
||||||
|
#define RESET_BARRIER ((uint16_t)550)
|
||||||
|
#define ONE_ZERO_BARRIER ((uint16_t)10)
|
||||||
|
|
||||||
|
#define ERR_TEMP_VAL ((int32_t)200000)
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint8_t bytes[8];
|
||||||
|
} OW_ID;
|
||||||
|
|
||||||
|
extern OW_ID id_array[];
|
||||||
|
|
||||||
|
#define OW_MAX_NUM 8
|
||||||
|
|
||||||
|
void init_ow_dmatimer();
|
||||||
|
void run_dmatimer();
|
||||||
|
extern uint8_t ow_done;
|
||||||
|
#define OW_READY() (ow_done)
|
||||||
|
void ow_dma_on();
|
||||||
|
uint8_t OW_add_byte(uint8_t ow_byte);
|
||||||
|
uint8_t OW_add_read_seq(uint8_t Nbytes);
|
||||||
|
void read_from_OWbuf(uint8_t start_idx, uint8_t N, uint8_t *outbuf);
|
||||||
|
void ow_reset();
|
||||||
|
uint8_t OW_get_reset_status();
|
||||||
|
|
||||||
|
extern int tum2buff_ctr;
|
||||||
|
#define OW_reset_buffer() do{tum2buff_ctr = 0;}while(0)
|
||||||
|
|
||||||
|
extern uint8_t ow_data_ready;
|
||||||
|
extern uint8_t ow_measurements_done;
|
||||||
|
#define OW_DATA_READY() (ow_data_ready)
|
||||||
|
#define OW_CLEAR_READY_FLAG() do{ow_data_ready = 0;}while(0)
|
||||||
|
#define OW_MEASUREMENTS_DONE() (ow_measurements_done)
|
||||||
|
#define OW_CLEAR_DONE_FLAG() do{ow_measurements_done = 0;}while(0)
|
||||||
|
|
||||||
|
void OW_process();
|
||||||
|
void OW_fill_next_ID();
|
||||||
|
void OW_send_read_seq();
|
||||||
|
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen);
|
||||||
|
|
||||||
|
extern int32_t temperature;
|
||||||
|
extern int8_t Ncur;
|
||||||
|
void OW_read_next_temp();
|
||||||
|
#define OW_current_temp() (temperature)
|
||||||
|
#define OW_current_num() (Ncur)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* thermometer commands
|
||||||
|
* send them with bus reset!
|
||||||
|
*/
|
||||||
|
// find devices
|
||||||
|
#define OW_SEARCH_ROM (0xf0)
|
||||||
|
// read device (when it is alone on the bus)
|
||||||
|
#define OW_READ_ROM (0x33)
|
||||||
|
// send device ID (after this command - 8 bytes of ID)
|
||||||
|
#define OW_MATCH_ROM (0x55)
|
||||||
|
// broadcast command
|
||||||
|
#define OW_SKIP_ROM (0xcc)
|
||||||
|
// find devices with critical conditions
|
||||||
|
#define OW_ALARM_SEARCH (0xec)
|
||||||
|
/*
|
||||||
|
* thermometer functions
|
||||||
|
* send them without bus reset!
|
||||||
|
*/
|
||||||
|
// start themperature reading
|
||||||
|
#define OW_CONVERT_T (0x44)
|
||||||
|
// write critical temperature to device's RAM
|
||||||
|
#define OW_SCRATCHPAD (0x4e)
|
||||||
|
// read whole device flash
|
||||||
|
#define OW_READ_SCRATCHPAD (0xbe)
|
||||||
|
// copy critical themperature from device's RAM to its EEPROM
|
||||||
|
#define OW_COPY_SCRATCHPAD (0x48)
|
||||||
|
// copy critical themperature from EEPROM to RAM (when power on this operation runs automatically)
|
||||||
|
#define OW_RECALL_E2 (0xb8)
|
||||||
|
// check whether there is devices wich power up from bus
|
||||||
|
#define OW_READ_POWER_SUPPLY (0xb4)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* thermometer identificator is: 8bits CRC, 48bits serial, 8bits device code (10h)
|
||||||
|
* Critical temperatures is T_H and T_L
|
||||||
|
* T_L is lowest allowed temperature
|
||||||
|
* T_H is highest -//-
|
||||||
|
* format T_H and T_L: 1bit sigh + 7bits of data
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RAM register:
|
||||||
|
* 0 - themperature: 1 ADU == 0.5 degrC
|
||||||
|
* 1 - sign (0 - T>0 degrC ==> T=byte0; 1 - T<0 degrC ==> T=byte0-0xff+1)
|
||||||
|
* 2 - T_H
|
||||||
|
* 3 - T_L
|
||||||
|
* 4 - 0xff (reserved)
|
||||||
|
* 5 - 0xff (reserved)
|
||||||
|
* 6 - COUNT_REMAIN (0x0c)
|
||||||
|
* 7 - COUNT PER DEGR (0x10)
|
||||||
|
* 8 - CRC
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ONEWIRE_H__
|
||||||
93
F1/1_wire/sync.c
Normal file
93
F1/1_wire/sync.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* implement mutexes for other type of MCU (which doesn't have strex & ldrex)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libopencm3/cm3/sync.h>
|
||||||
|
|
||||||
|
/* DMB is supported on CM0 */
|
||||||
|
void __dmb()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("dmb");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("strex %0, %2, [%1]"
|
||||||
|
: "=&r" (res) : "r" (addr), "r" (val));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m)
|
||||||
|
{
|
||||||
|
uint32_t status = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Wait until the mutex is unlocked. */
|
||||||
|
while (__ldrex(m) != MUTEX_UNLOCKED);
|
||||||
|
|
||||||
|
/* Try to acquire it. */
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
|
||||||
|
/* Did we get it? If not then try again. */
|
||||||
|
} while (status != 0);
|
||||||
|
|
||||||
|
/* Execute the mysterious Data Memory Barrier instruction! */
|
||||||
|
__dmb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_unlock(mutex_t *m)
|
||||||
|
{
|
||||||
|
/* Ensure accesses to protected resource are finished */
|
||||||
|
__dmb();
|
||||||
|
|
||||||
|
/* Free the lock. */
|
||||||
|
*m = MUTEX_UNLOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to lock mutex
|
||||||
|
* if it's already locked or there was error in STREX, return MUTEX_LOCKED
|
||||||
|
* else return MUTEX_UNLOCKED
|
||||||
|
*/
|
||||||
|
mutex_t mutex_trylock(mutex_t *m){
|
||||||
|
uint32_t status = 0;
|
||||||
|
mutex_t old_lock = __ldrex(m); // get mutex value
|
||||||
|
// set mutex
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
if(status == 0) __dmb();
|
||||||
|
else old_lock = MUTEX_LOCKED;
|
||||||
|
return old_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
53
F1/1_wire/sync.h
Normal file
53
F1/1_wire/sync.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBOPENCM3_CM3_SYNC_H
|
||||||
|
#define LIBOPENCM3_CM3_SYNC_H
|
||||||
|
|
||||||
|
void __dmb(void);
|
||||||
|
|
||||||
|
/* Implements synchronisation primitives as discussed in the ARM document
|
||||||
|
* DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M
|
||||||
|
* Architecture Reference Manual.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* --- Exclusive load and store instructions ------------------------------- */
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr);
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr);
|
||||||
|
|
||||||
|
/* --- Convenience functions ----------------------------------------------- */
|
||||||
|
|
||||||
|
/* Here we implement some simple synchronisation primitives. */
|
||||||
|
|
||||||
|
typedef uint32_t mutex_t;
|
||||||
|
|
||||||
|
#define MUTEX_UNLOCKED 0
|
||||||
|
#define MUTEX_LOCKED 1
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m);
|
||||||
|
void mutex_unlock(mutex_t *m);
|
||||||
|
mutex_t mutex_trylock(mutex_t *m);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
243
F1/1_wire/user_proto.c
Normal file
243
F1/1_wire/user_proto.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "onewire.h"
|
||||||
|
|
||||||
|
// integer value given by user
|
||||||
|
static volatile int32_t User_value = 0;
|
||||||
|
enum{
|
||||||
|
UVAL_START, // user start to write integer value
|
||||||
|
UVAL_ENTERED, // value entered but not printed
|
||||||
|
UVAL_BAD // entered bad value
|
||||||
|
};
|
||||||
|
uint8_t Uval_ready = UVAL_BAD;
|
||||||
|
|
||||||
|
int read_int(char *buf, int cnt);
|
||||||
|
|
||||||
|
intfun I = NULL; // function to process entered integer
|
||||||
|
|
||||||
|
#define READINT() do{i += read_int(&buf[i+1], len-i-1);}while(0)
|
||||||
|
|
||||||
|
void help(){
|
||||||
|
P("H\tshow this help\n");
|
||||||
|
P("I\ttest entering integer value\n");
|
||||||
|
P("T\tshow current approx. time\n");
|
||||||
|
P("1\tswitch LED D1 state\n");
|
||||||
|
P("2\tswitch LED D2 state\n");
|
||||||
|
P("R\tstart reading temperature\n");
|
||||||
|
P("P\tread DS18 ID\n");
|
||||||
|
P("Q\tget temperature\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show entered integer value
|
||||||
|
*/
|
||||||
|
uint8_t show_int(int32_t v){
|
||||||
|
newline();
|
||||||
|
print_int(v);
|
||||||
|
newline();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse command buffer buf with length len
|
||||||
|
* return 0 if buffer processed or len if there's not enough data in buffer
|
||||||
|
*/
|
||||||
|
int parse_incoming_buf(char *buf, int len){
|
||||||
|
uint8_t command;
|
||||||
|
//uint32_t utmp;
|
||||||
|
int i = 0;
|
||||||
|
if(Uval_ready == UVAL_START){ // we are in process of user's value reading
|
||||||
|
i += read_int(buf, len);
|
||||||
|
}
|
||||||
|
if(Uval_ready == UVAL_ENTERED){
|
||||||
|
//print_int(User_value); // printout readed integer value for error control
|
||||||
|
Uval_ready = UVAL_BAD; // clear Uval
|
||||||
|
I(User_value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(; i < len; i++){
|
||||||
|
command = buf[i];
|
||||||
|
if(!command) continue; // omit zero
|
||||||
|
switch (command){
|
||||||
|
case '1':
|
||||||
|
gpio_toggle(LEDS_PORT, LED_D1_PIN);
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
gpio_toggle(LEDS_PORT, LED_D2_PIN);
|
||||||
|
break;
|
||||||
|
case 'H': // show help
|
||||||
|
help();
|
||||||
|
break;
|
||||||
|
case 'I': // enter integer & show its value
|
||||||
|
I = show_int;
|
||||||
|
READINT();
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
newline();
|
||||||
|
print_int(Timer); // be careful for Time >= 2^{31}!!!
|
||||||
|
newline();
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
OW_fill_next_ID();
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
if(OW_MEASUREMENTS_DONE())
|
||||||
|
OW_read_next_temp();
|
||||||
|
else
|
||||||
|
P("Wait for measurements ends or start another\n");
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
OW_send_read_seq();
|
||||||
|
break;
|
||||||
|
case '\n': // show newline, space and tab as is
|
||||||
|
case '\r':
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
command = '?'; // echo '?' on unknown command in byte mode
|
||||||
|
}
|
||||||
|
usb_send(command); // echo readed byte
|
||||||
|
}
|
||||||
|
return 0; // all data processed - 0 bytes leave in buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send char array wrd thru USB or UART
|
||||||
|
*/
|
||||||
|
void prnt(uint8_t *wrd){
|
||||||
|
if(!wrd) return;
|
||||||
|
while(*wrd) usb_send(*wrd++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ERR(char *wrd){
|
||||||
|
if(!wrd) return;
|
||||||
|
while(*wrd) usb_send(*((uint8_t*)wrd++));
|
||||||
|
usb_send('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from TTY integer value given by user (in DEC).
|
||||||
|
* Reading stops on first non-numeric symbol.
|
||||||
|
* To work with symbol terminals reading don't stops on buffer's end,
|
||||||
|
* it waits for first non-numeric char.
|
||||||
|
* When working on string terminals, terminate string by '\n', 0 or any other symbol
|
||||||
|
* @param buf - buffer to read from
|
||||||
|
* @param cnt - buffer length
|
||||||
|
* @return amount of readed symbols
|
||||||
|
*/
|
||||||
|
int read_int(char *buf, int cnt){
|
||||||
|
int readed = 0, i;
|
||||||
|
static int enteredDigits; // amount of entered digits
|
||||||
|
static int sign; // sign of readed value
|
||||||
|
if(Uval_ready){ // this is first run
|
||||||
|
Uval_ready = UVAL_START; // clear flag
|
||||||
|
enteredDigits = 0; // 0 digits entered
|
||||||
|
User_value = 0; // clear value
|
||||||
|
sign = 1; // clear sign
|
||||||
|
}
|
||||||
|
if(!cnt) return 0;
|
||||||
|
for(i = 0; i < cnt; i++, readed++){
|
||||||
|
uint8_t chr = buf[i];
|
||||||
|
if(chr == '-'){
|
||||||
|
if(enteredDigits == 0){ // sign should be first
|
||||||
|
sign = -1;
|
||||||
|
continue;
|
||||||
|
}else{ // '-' after number - reject entered value
|
||||||
|
Uval_ready = UVAL_BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(chr < '0' || chr > '9'){
|
||||||
|
if(enteredDigits)
|
||||||
|
Uval_ready = UVAL_ENTERED;
|
||||||
|
else
|
||||||
|
Uval_ready = UVAL_BAD; // bad symbol
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
User_value = User_value * 10 + (int32_t)(chr - '0');
|
||||||
|
enteredDigits++;
|
||||||
|
}
|
||||||
|
if(Uval_ready == UVAL_ENTERED) // reading has met an non-numeric character
|
||||||
|
User_value *= sign;
|
||||||
|
return readed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print buff as hex values
|
||||||
|
* @param buf - buffer to print
|
||||||
|
* @param l - buf length
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l){
|
||||||
|
void putc(uint8_t c){
|
||||||
|
if(c < 10)
|
||||||
|
usb_send(c + '0');
|
||||||
|
else
|
||||||
|
usb_send(c + 'a' - 10);
|
||||||
|
}
|
||||||
|
usb_send('0'); usb_send('x'); // prefix 0x
|
||||||
|
while(l--){
|
||||||
|
putc(buff[l] >> 4);
|
||||||
|
putc(buff[l] & 0x0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print decimal integer value
|
||||||
|
* @param N - value to print
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_int(int32_t N){
|
||||||
|
uint8_t buf[10], L = 0;
|
||||||
|
if(N < 0){
|
||||||
|
usb_send('-');
|
||||||
|
N = -N;
|
||||||
|
}
|
||||||
|
if(N){
|
||||||
|
while(N){
|
||||||
|
buf[L++] = N % 10 + '0';
|
||||||
|
N /= 10;
|
||||||
|
}
|
||||||
|
while(L--) usb_send(buf[L]);
|
||||||
|
}else usb_send('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
void OW_printID(uint8_t N){
|
||||||
|
void putc(uint8_t c){
|
||||||
|
if(c < 10)
|
||||||
|
usb_send(c + '0');
|
||||||
|
else
|
||||||
|
usb_send(c + 'a' - 10);
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
uint8_t *b = id_array[N].bytes;
|
||||||
|
usb_send('0'); usb_send('x'); // prefix 0x
|
||||||
|
for(i = 0; i < 8; i++){
|
||||||
|
putc(b[i] >> 4);
|
||||||
|
putc(b[i] & 0x0f);
|
||||||
|
}
|
||||||
|
usb_send('\n');
|
||||||
|
}
|
||||||
51
F1/1_wire/user_proto.h
Normal file
51
F1/1_wire/user_proto.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __USER_PROTO_H__
|
||||||
|
#define __USER_PROTO_H__
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
|
||||||
|
// shorthand for prnt
|
||||||
|
#define P(arg) do{prnt((uint8_t*)arg);}while(0)
|
||||||
|
// debug message - over USB
|
||||||
|
#ifdef EBUG
|
||||||
|
#define DBG(a) do{prnt((uint8_t*)a);}while(0)
|
||||||
|
#define INT(N) do{print_int(N);}while(0)
|
||||||
|
#else
|
||||||
|
#define DBG(a)
|
||||||
|
#define INT(N)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t (*intfun)(int32_t);
|
||||||
|
|
||||||
|
void ERR(char *wrd);
|
||||||
|
void prnt(uint8_t *wrd);
|
||||||
|
#define newline() usb_send('\n')
|
||||||
|
|
||||||
|
void print_int(int32_t N);
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l);
|
||||||
|
|
||||||
|
int parse_incoming_buf(char *buf, int len);
|
||||||
|
void OW_printID(uint8_t N);
|
||||||
|
|
||||||
|
#endif // __USER_PROTO_H__
|
||||||
133
F1/DMA_GPIO/Makefile
Normal file
133
F1/DMA_GPIO/Makefile
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
BINARY = dma_gpio
|
||||||
|
BOOTPORT ?= /dev/ttyUSB0
|
||||||
|
BOOTSPEED ?= 115200
|
||||||
|
# change this linking script depending on particular MCU model,
|
||||||
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
|
LDSCRIPT = ld/stm32f103x8.ld
|
||||||
|
LIBNAME = opencm3_stm32f1
|
||||||
|
DEFS = -DSTM32F1 -DEBUG
|
||||||
|
|
||||||
|
OBJDIR = mk
|
||||||
|
INDEPENDENT_HEADERS=
|
||||||
|
|
||||||
|
FP_FLAGS ?= -msoft-float
|
||||||
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Executables
|
||||||
|
PREFIX ?= arm-none-eabi
|
||||||
|
|
||||||
|
RM := rm -f
|
||||||
|
RMDIR := rmdir
|
||||||
|
CC := $(PREFIX)-gcc
|
||||||
|
LD := $(PREFIX)-gcc
|
||||||
|
AR := $(PREFIX)-ar
|
||||||
|
AS := $(PREFIX)-as
|
||||||
|
OBJCOPY := $(PREFIX)-objcopy
|
||||||
|
OBJDUMP := $(PREFIX)-objdump
|
||||||
|
GDB := $(PREFIX)-gdb
|
||||||
|
STFLASH = $(shell which st-flash)
|
||||||
|
STBOOT = $(shell which stm32flash)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Source files
|
||||||
|
LDSCRIPT ?= $(BINARY).ld
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||||
|
|
||||||
|
ifeq ($(strip $(OPENCM3_DIR)),)
|
||||||
|
OPENCM3_DIR := /usr/local/arm-none-eabi
|
||||||
|
$(info Using $(OPENCM3_DIR) path to library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
||||||
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
||||||
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C flags
|
||||||
|
CFLAGS += -Os -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
|
CFLAGS += -Wredundant-decls
|
||||||
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C & C++ preprocessor common flags
|
||||||
|
CPPFLAGS += -MD
|
||||||
|
CPPFLAGS += -Wall -Werror
|
||||||
|
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS += --static -nostartfiles
|
||||||
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
|
LDFLAGS += -Wl,-Map=$(*).map
|
||||||
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Used libraries
|
||||||
|
LDLIBS += -l$(LIBNAME)
|
||||||
|
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||||
|
|
||||||
|
.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
|
BIN := $(BINARY).bin
|
||||||
|
HEX := $(BINARY).hex
|
||||||
|
|
||||||
|
all: bin
|
||||||
|
|
||||||
|
elf: $(ELF)
|
||||||
|
bin: $(BIN)
|
||||||
|
hex: $(HEX)
|
||||||
|
list: $(LIST)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@printf " CC $<\n"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
%.h: ;
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@printf " OBJCOPY $(BIN)\n"
|
||||||
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|
||||||
|
$(HEX): $(ELF)
|
||||||
|
@printf " OBJCOPY $(HEX)\n"
|
||||||
|
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||||
|
|
||||||
|
$(LIST): $(ELF)
|
||||||
|
@printf " OBJDUMP $(LIST)\n"
|
||||||
|
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
|
||||||
|
@printf " LD $(ELF)\n"
|
||||||
|
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf " CLEAN\n"
|
||||||
|
$(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||||
|
$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
flash: $(BIN)
|
||||||
|
@printf " FLASH $(BIN)\n"
|
||||||
|
$(STFLASH) write $(BIN) 0x8000000
|
||||||
|
|
||||||
|
boot: $(BIN)
|
||||||
|
@printf " LOAD $(BIN) through bootloader\n"
|
||||||
|
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||||
|
|
||||||
|
.PHONY: clean elf hex list flash boot
|
||||||
|
|
||||||
|
#-include $(OBJS:.o=.d)
|
||||||
1
F1/DMA_GPIO/README
Normal file
1
F1/DMA_GPIO/README
Normal file
@ -0,0 +1 @@
|
|||||||
|
simple 8-bit FSMC emulation with DMA
|
||||||
310
F1/DMA_GPIO/cdcacm.c
Normal file
310
F1/DMA_GPIO/cdcacm.c
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
// Buffer for USB Tx
|
||||||
|
static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE];
|
||||||
|
static uint8_t USB_Tx_ptr = 0;
|
||||||
|
// connection flag
|
||||||
|
uint8_t USB_connected = 0;
|
||||||
|
static const struct usb_device_descriptor dev = {
|
||||||
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
.bDeviceClass = USB_CLASS_CDC,
|
||||||
|
.bDeviceSubClass = 0,
|
||||||
|
.bDeviceProtocol = 0,
|
||||||
|
.bMaxPacketSize0 = 64,
|
||||||
|
.idVendor = 0x0483,
|
||||||
|
.idProduct = 0x5740,
|
||||||
|
.bcdDevice = 0x0200,
|
||||||
|
.iManufacturer = 1,
|
||||||
|
.iProduct = 2,
|
||||||
|
.iSerialNumber = 3,
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data
|
||||||
|
int usbdatalen = 0; // lenght of received data
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This notification endpoint isn't implemented. According to CDC spec its
|
||||||
|
* optional, but its absence causes a NULL pointer dereference in Linux
|
||||||
|
* cdc_acm driver.
|
||||||
|
*/
|
||||||
|
static const struct usb_endpoint_descriptor comm_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x83,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
|
.wMaxPacketSize = 16,
|
||||||
|
.bInterval = 255,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_endpoint_descriptor data_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x01,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}, {
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x82,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
struct usb_cdc_header_descriptor header;
|
||||||
|
struct usb_cdc_call_management_descriptor call_mgmt;
|
||||||
|
struct usb_cdc_acm_descriptor acm;
|
||||||
|
struct usb_cdc_union_descriptor cdc_union;
|
||||||
|
} __attribute__((packed)) cdcacm_functional_descriptors = {
|
||||||
|
.header = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
|
||||||
|
.bcdCDC = 0x0110,
|
||||||
|
},
|
||||||
|
.call_mgmt = {
|
||||||
|
.bFunctionLength =
|
||||||
|
sizeof(struct usb_cdc_call_management_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
.bDataInterface = 1,
|
||||||
|
},
|
||||||
|
.acm = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
},
|
||||||
|
.cdc_union = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||||
|
.bControlInterface = 0,
|
||||||
|
.bSubordinateInterface0 = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor comm_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 0,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = comm_endp,
|
||||||
|
|
||||||
|
.extra = &cdcacm_functional_descriptors,
|
||||||
|
.extralen = sizeof(cdcacm_functional_descriptors),
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor data_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 2,
|
||||||
|
.bInterfaceClass = USB_CLASS_DATA,
|
||||||
|
.bInterfaceSubClass = 0,
|
||||||
|
.bInterfaceProtocol = 0,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = data_endp,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface ifaces[] = {{
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = comm_iface,
|
||||||
|
}, {
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = data_iface,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_config_descriptor config = {
|
||||||
|
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||||
|
.wTotalLength = 0,
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = 1,
|
||||||
|
.iConfiguration = 0,
|
||||||
|
.bmAttributes = 0x80,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
|
||||||
|
.interface = ifaces,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *usb_strings[] = {
|
||||||
|
"Organisation, author",
|
||||||
|
"device",
|
||||||
|
"version",
|
||||||
|
};
|
||||||
|
|
||||||
|
// default line coding: B115200, 1stop, 8bits, parity none
|
||||||
|
struct usb_cdc_line_coding linecoding = {
|
||||||
|
.dwDTERate = 115200,
|
||||||
|
.bCharFormat = USB_CDC_1_STOP_BITS,
|
||||||
|
.bParityType = USB_CDC_NO_PARITY,
|
||||||
|
.bDataBits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Buffer to be used for control requests. */
|
||||||
|
uint8_t usbd_control_buffer[128];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function runs every time it gets a request for control parameters get/set
|
||||||
|
* parameter SET_LINE_CODING used to change USART1 parameters: if you want to
|
||||||
|
* change them, just connect through USB with required parameters
|
||||||
|
*/
|
||||||
|
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
|
||||||
|
uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){
|
||||||
|
(void)complete;
|
||||||
|
(void)buf;
|
||||||
|
(void)usbd_dev;
|
||||||
|
char local_buf[10];
|
||||||
|
struct usb_cdc_line_coding lc;
|
||||||
|
|
||||||
|
switch (req->bRequest) {
|
||||||
|
case SET_CONTROL_LINE_STATE:{
|
||||||
|
if(req->wValue){ // terminal is opened
|
||||||
|
USB_connected = 1;
|
||||||
|
}else{ // terminal is closed
|
||||||
|
USB_connected = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This Linux cdc_acm driver requires this to be implemented
|
||||||
|
* even though it's optional in the CDC spec, and we don't
|
||||||
|
* advertise it in the ACM functional descriptor.
|
||||||
|
*/
|
||||||
|
struct usb_cdc_notification *notif = (void *)local_buf;
|
||||||
|
/* We echo signals back to host as notification. */
|
||||||
|
notif->bmRequestType = 0xA1;
|
||||||
|
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
|
||||||
|
notif->wValue = 0;
|
||||||
|
notif->wIndex = 0;
|
||||||
|
notif->wLength = 2;
|
||||||
|
local_buf[8] = req->wValue & 3;
|
||||||
|
local_buf[9] = 0;
|
||||||
|
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
|
||||||
|
}break;
|
||||||
|
case SET_LINE_CODING:
|
||||||
|
if (!len || (*len != sizeof(struct usb_cdc_line_coding)))
|
||||||
|
return 0;
|
||||||
|
memcpy((void *)&lc, (void *)*buf, *len);
|
||||||
|
// Mark & Space parity don't support by hardware, check it
|
||||||
|
if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){
|
||||||
|
return 0; // error
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_LINE_CODING: // return linecoding buffer
|
||||||
|
if(len && *len == sizeof(struct usb_cdc_line_coding))
|
||||||
|
memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen);
|
||||||
|
usbdatalen += len;
|
||||||
|
if(usbdatalen >= USB_RX_DATA_SIZE){ // buffer overflow - drop all its contents
|
||||||
|
usbdatalen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
|
||||||
|
{
|
||||||
|
(void)wValue;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
|
|
||||||
|
usbd_register_control_callback(
|
||||||
|
usbd_dev,
|
||||||
|
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||||
|
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||||
|
cdcacm_control_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbd_device *current_usb = NULL;
|
||||||
|
|
||||||
|
usbd_device *USB_init(){
|
||||||
|
current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config,
|
||||||
|
usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
if(!current_usb) return NULL;
|
||||||
|
usbd_register_set_config_callback(current_usb, cdcacm_set_config);
|
||||||
|
return current_usb;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_t send_block_mutex = MUTEX_UNLOCKED;
|
||||||
|
/**
|
||||||
|
* Put byte into USB buffer to send
|
||||||
|
* @param byte - a byte to put into a buffer
|
||||||
|
*/
|
||||||
|
void usb_send(uint8_t byte){
|
||||||
|
mutex_lock(&send_block_mutex);
|
||||||
|
USB_Tx_Buffer[USB_Tx_ptr++] = byte;
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it!
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send all data in buffer over USB
|
||||||
|
* this function runs when buffer is full or on SysTick
|
||||||
|
*/
|
||||||
|
void usb_send_buffer(){
|
||||||
|
if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return;
|
||||||
|
if(USB_Tx_ptr){
|
||||||
|
if(current_usb && USB_connected){
|
||||||
|
// usbd_ep_write_packet return 0 if previous packet isn't transmit yet
|
||||||
|
while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr));
|
||||||
|
usbd_poll(current_usb);
|
||||||
|
}
|
||||||
|
USB_Tx_ptr = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
}
|
||||||
54
F1/DMA_GPIO/cdcacm.h
Normal file
54
F1/DMA_GPIO/cdcacm.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ccdcacm.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __CCDCACM_H__
|
||||||
|
#define __CCDCACM_H__
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
|
// commands through EP0
|
||||||
|
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define GET_ENCAPSULATED_RESPONSE 0x01
|
||||||
|
#define SET_COMM_FEATURE 0x02
|
||||||
|
#define GET_COMM_FEATURE 0x03
|
||||||
|
#define CLEAR_COMM_FEATURE 0x04
|
||||||
|
#define SET_LINE_CODING 0x20
|
||||||
|
#define GET_LINE_CODING 0x21
|
||||||
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define SEND_BREAK 0x23
|
||||||
|
|
||||||
|
// Size of input/output buffers
|
||||||
|
#define USB_TX_DATA_SIZE 64
|
||||||
|
#define USB_RX_DATA_SIZE 64
|
||||||
|
|
||||||
|
// USB connection flag
|
||||||
|
extern uint8_t USB_connected;
|
||||||
|
extern struct usb_cdc_line_coding linecoding;
|
||||||
|
|
||||||
|
extern uint8_t usbdatabuf[];
|
||||||
|
extern int usbdatalen;
|
||||||
|
|
||||||
|
usbd_device *USB_init();
|
||||||
|
void usb_send(uint8_t byte);
|
||||||
|
void usb_send_buffer();
|
||||||
|
|
||||||
|
#endif // __CCDCACM_H__
|
||||||
BIN
F1/DMA_GPIO/dma_gpio.bin
Executable file
BIN
F1/DMA_GPIO/dma_gpio.bin
Executable file
Binary file not shown.
97
F1/DMA_GPIO/dmagpio.c
Normal file
97
F1/DMA_GPIO/dmagpio.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* dmagpio.c
|
||||||
|
*
|
||||||
|
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dmagpio.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
int transfer_complete = 0;
|
||||||
|
static uint16_t gpiobuff[128] = {0};
|
||||||
|
|
||||||
|
void dmagpio_init(){
|
||||||
|
// init TIM2 & DMA1ch2 (TIM2UP)
|
||||||
|
rcc_periph_clock_enable(RCC_TIM2);
|
||||||
|
rcc_periph_clock_enable(RCC_DMA1);
|
||||||
|
timer_reset(TIM2);
|
||||||
|
// timer have frequency of 1MHz
|
||||||
|
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
|
||||||
|
// 72MHz div 18 = 4MHz
|
||||||
|
TIM2_PSC = 0; // prescaler is (div - 1)
|
||||||
|
TIM2_ARR = 1; // 36MHz (6.25)
|
||||||
|
TIM2_DIER = TIM_DIER_UDE;// | TIM_DIER_UIE;
|
||||||
|
//nvic_enable_irq(NVIC_TIM2_IRQ);
|
||||||
|
|
||||||
|
dma_channel_reset(DMA1, DMA_CHANNEL2);
|
||||||
|
// mem2mem, medium prio, 8bits, memory increment, read from mem, transfer complete en
|
||||||
|
//DMA1_CCR2 = DMA_CCR_MEM2MEM | DMA_CCR_PL_MEDIUM | DMA_CCR_MSIZE_16BIT |
|
||||||
|
DMA1_CCR2 = DMA_CCR_PL_MEDIUM | DMA_CCR_MSIZE_16BIT |
|
||||||
|
DMA_CCR_PSIZE_16BIT | DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE | DMA_CCR_TEIE ;
|
||||||
|
nvic_enable_irq(NVIC_DMA1_CHANNEL2_IRQ);
|
||||||
|
// target address:
|
||||||
|
DMA1_CPAR2 = DMAGPIO_TARGADDR;
|
||||||
|
DMA1_CMAR2 = (uint32_t) gpiobuff;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void tim2_isr(){
|
||||||
|
if(TIM2_SR & TIM_SR_UIF){ // update interrupt
|
||||||
|
++cntr;
|
||||||
|
GPIOA_ODR = gpiobuff[curidx];
|
||||||
|
if(++curidx >= len){
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_CEN;
|
||||||
|
transfer_complete = 1;
|
||||||
|
}
|
||||||
|
TIM2_SR = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dmagpio_transfer(uint8_t *databuf, uint32_t length){
|
||||||
|
while(DMA1_CCR2 & DMA_CCR_EN);
|
||||||
|
transfer_complete = 0;
|
||||||
|
DMA1_IFCR = 0xff00; // clear all flags for ch2
|
||||||
|
// memory address
|
||||||
|
//DMA1_CMAR2 = (uint32_t) databuf;
|
||||||
|
// buffer length
|
||||||
|
// DMA1_CPAR2 = DMAGPIO_TARGADDR;
|
||||||
|
// DMA1_CMAR2 = (uint32_t) gpiobuff;
|
||||||
|
DMA1_CNDTR2 = length;
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < length; ++i) gpiobuff[i] = databuf[i];
|
||||||
|
TIM2_CR1 |= TIM_CR1_CEN; // run timer
|
||||||
|
DMA1_CCR2 |= DMA_CCR_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dma1_channel2_isr(){
|
||||||
|
if(DMA1_ISR & DMA_ISR_TCIF2){
|
||||||
|
transfer_complete = 1;
|
||||||
|
// stop timer & turn off DMA
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_CEN;
|
||||||
|
DMA1_CCR2 &= ~DMA_CCR_EN;
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTCIF2; // clear flag
|
||||||
|
/* uint32_t arr = TIM2_ARR;
|
||||||
|
if(arr == 1) TIM2_ARR = 71;
|
||||||
|
else TIM2_ARR = arr - 1;*/
|
||||||
|
}else if(DMA1_ISR & DMA_ISR_TEIF2){
|
||||||
|
P("Error\n");
|
||||||
|
DMA1_IFCR = DMA_IFCR_CTEIF2;
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_CEN;
|
||||||
|
DMA1_CCR2 &= ~DMA_CCR_EN;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
F1/DMA_GPIO/dmagpio.h
Normal file
32
F1/DMA_GPIO/dmagpio.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* dmagpio.h
|
||||||
|
*
|
||||||
|
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef __DMAGPIO_H__
|
||||||
|
#define __DMAGPIO_H__
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
void dmagpio_init();
|
||||||
|
void dmagpio_transfer(uint8_t *databuf, uint32_t length);
|
||||||
|
extern int transfer_complete;
|
||||||
|
|
||||||
|
#endif // __DMAGPIO_H__
|
||||||
72
F1/DMA_GPIO/hardware_ini.c
Normal file
72
F1/DMA_GPIO/hardware_ini.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.c - functions for HW initialisation
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All hardware-dependent initialisation & definition should be placed here
|
||||||
|
* and in hardware_ini.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO initialisaion: clocking + pins setup
|
||||||
|
*/
|
||||||
|
void GPIO_init(){
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
|
||||||
|
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN |
|
||||||
|
RCC_APB2ENR_IOPEEN);
|
||||||
|
// DMAGPIO
|
||||||
|
gpio_set_mode(DMAGPIO_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
|
||||||
|
DMAGPIO_PINS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Buttons: pull-up input
|
||||||
|
gpio_set_mode(BTNS_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
|
||||||
|
BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// turn on pull-up
|
||||||
|
gpio_set(BTNS_PORT, BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// LEDS: opendrain output
|
||||||
|
gpio_set_mode(LEDS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
|
||||||
|
LED_D1_PIN | LED_D2_PIN);
|
||||||
|
// turn off LEDs
|
||||||
|
gpio_set(LEDS_PORT, LED_D1_PIN | LED_D2_PIN);
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
// USB_DISC: push-pull
|
||||||
|
gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ,
|
||||||
|
GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN);
|
||||||
|
// USB_POWER: open drain, externall pull down with R7 (22k)
|
||||||
|
gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT,
|
||||||
|
GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SysTick used for system timer with period of 1ms
|
||||||
|
*/
|
||||||
|
void SysTick_init(){
|
||||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
||||||
|
systick_set_reload(8999); // 9000 pulses: 1kHz
|
||||||
|
systick_interrupt_enable();
|
||||||
|
systick_counter_enable();
|
||||||
|
}
|
||||||
65
F1/DMA_GPIO/hardware_ini.h
Normal file
65
F1/DMA_GPIO/hardware_ini.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __HARDWARE_INI_H__
|
||||||
|
#define __HARDWARE_INI_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timers:
|
||||||
|
* SysTick - system time
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void GPIO_init();
|
||||||
|
void SysTick_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA to GPIO port & pins (mask)
|
||||||
|
*/
|
||||||
|
#define DMAGPIO_PORT GPIOA
|
||||||
|
#define DMAGPIO_PINS 0xff
|
||||||
|
#define DMAGPIO_TARGADDR ((uint32_t)&(GPIOA_ODR))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB interface
|
||||||
|
* connect boot1 jumper to gnd, boot0 to gnd; and reconnect boot0 to +3.3 to boot flash
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
// USB_DICS (disconnect) - PC11
|
||||||
|
#define USB_DISC_PIN GPIO11
|
||||||
|
#define USB_DISC_PORT GPIOC
|
||||||
|
// USB_POWER (high level when USB connected to PC)
|
||||||
|
#define USB_POWER_PIN GPIO10
|
||||||
|
#define USB_POWER_PORT GPIOC
|
||||||
|
// change signal level on USB diconnect pin
|
||||||
|
#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level
|
||||||
|
// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level
|
||||||
|
#define usb_disconnect() usb_disc_high()
|
||||||
|
#define usb_connect() usb_disc_low()
|
||||||
|
*/
|
||||||
|
// my simple devboard have no variants for programmed connection/disconnection of USB
|
||||||
|
#define usb_disconnect()
|
||||||
|
#define usb_connect()
|
||||||
|
|
||||||
|
#endif // __HARDWARE_INI_H__
|
||||||
9
F1/DMA_GPIO/ld/devices.data
Normal file
9
F1/DMA_GPIO/ld/devices.data
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
stm32f103?4* stm32f1 ROM=16K RAM=6K
|
||||||
|
stm32f103?6* stm32f1 ROM=32K RAM=10K
|
||||||
|
stm32f103?8* stm32f1 ROM=64K RAM=20K
|
||||||
|
stm32f103?b* stm32f1 ROM=128K RAM=20K
|
||||||
|
stm32f103?c* stm32f1 ROM=256K RAM=48K
|
||||||
|
stm32f103?d* stm32f1 ROM=384K RAM=64K
|
||||||
|
stm32f103?e* stm32f1 ROM=512K RAM=64K
|
||||||
|
stm32f103?f* stm32f1 ROM=768K RAM=96K
|
||||||
|
stm32f103?g* stm32f1 ROM=1024K RAM=96K
|
||||||
31
F1/DMA_GPIO/ld/stm32f103x4.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103x4.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103x6.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103x6.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103x8.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103x8.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xB.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xB.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xC.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xC.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xD.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xD.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xE.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xE.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xF.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xF.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/DMA_GPIO/ld/stm32f103xG.ld
Normal file
31
F1/DMA_GPIO/ld/stm32f103xG.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
90
F1/DMA_GPIO/main.c
Normal file
90
F1/DMA_GPIO/main.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "dmagpio.h"
|
||||||
|
|
||||||
|
volatile uint32_t Timer = 0; // global timer (milliseconds)
|
||||||
|
usbd_device *usbd_dev;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
uint32_t Old_timer = 0;
|
||||||
|
|
||||||
|
// RCC clocking: 8MHz oscillator -> 72MHz system
|
||||||
|
rcc_clock_setup_in_hse_8mhz_out_72mhz();
|
||||||
|
|
||||||
|
GPIO_init();
|
||||||
|
|
||||||
|
usb_disconnect(); // turn off USB while initializing all
|
||||||
|
|
||||||
|
// USB
|
||||||
|
usbd_dev = USB_init();
|
||||||
|
|
||||||
|
// SysTick is a system timer with 1ms period
|
||||||
|
SysTick_init();
|
||||||
|
dmagpio_init();
|
||||||
|
|
||||||
|
usb_connect(); // turn on USB
|
||||||
|
|
||||||
|
int oldusblen = 0;
|
||||||
|
while(1){
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
if(usbdatalen != oldusblen){ // there's something in USB buffer
|
||||||
|
parse_incoming_buf(usbdatabuf, &usbdatalen);
|
||||||
|
oldusblen = usbdatalen;
|
||||||
|
}
|
||||||
|
if(transfer_complete){
|
||||||
|
P("transfered\n");
|
||||||
|
transfer_complete = 0;
|
||||||
|
}
|
||||||
|
if(Timer - Old_timer > 999){ // one-second cycle
|
||||||
|
Old_timer += 1000;
|
||||||
|
}else if(Timer < Old_timer){ // Timer overflow
|
||||||
|
Old_timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SysTick interrupt: increment global time & send data buffer through USB
|
||||||
|
*/
|
||||||
|
void sys_tick_handler(){
|
||||||
|
Timer++;
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pause function, delay in ms
|
||||||
|
void Delay(uint16_t _U_ time){
|
||||||
|
uint32_t waitto = Timer + time;
|
||||||
|
while(Timer < waitto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print current time in milliseconds: 4 bytes for ovrvlow + 4 bytes for time
|
||||||
|
* with ' ' as delimeter
|
||||||
|
*/
|
||||||
|
void print_time(){
|
||||||
|
print_int(Timer);
|
||||||
|
}
|
||||||
53
F1/DMA_GPIO/main.h
Normal file
53
F1/DMA_GPIO/main.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* main.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MAIN_H__
|
||||||
|
#define __MAIN_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
#include <libopencm3/stm32/gpio.h>
|
||||||
|
#include <libopencm3/stm32/usart.h>
|
||||||
|
#include <libopencm3/cm3/nvic.h>
|
||||||
|
#include <libopencm3/usb/cdc.h>
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
#include <libopencm3/cm3/systick.h>
|
||||||
|
#include <libopencm3/stm32/rcc.h>
|
||||||
|
#include <libopencm3/stm32/adc.h>
|
||||||
|
#include <libopencm3/stm32/dma.h>
|
||||||
|
#include <libopencm3/stm32/spi.h>
|
||||||
|
#include <libopencm3/stm32/timer.h>
|
||||||
|
|
||||||
|
#include "sync.h" // mutexes
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
#define _U_ __attribute__((__unused__))
|
||||||
|
#define U8(x) ((uint8_t) x)
|
||||||
|
#define U16(x) ((uint16_t) x)
|
||||||
|
#define U32(x) ((uint32_t) x)
|
||||||
|
|
||||||
|
extern volatile uint32_t Timer; // global timer (milliseconds)
|
||||||
|
void Delay(uint16_t time);
|
||||||
|
|
||||||
|
#endif // __MAIN_H__
|
||||||
|
|
||||||
93
F1/DMA_GPIO/sync.c
Normal file
93
F1/DMA_GPIO/sync.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* implement mutexes for other type of MCU (which doesn't have strex & ldrex)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libopencm3/cm3/sync.h>
|
||||||
|
|
||||||
|
/* DMB is supported on CM0 */
|
||||||
|
void __dmb()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("dmb");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("strex %0, %2, [%1]"
|
||||||
|
: "=&r" (res) : "r" (addr), "r" (val));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m)
|
||||||
|
{
|
||||||
|
uint32_t status = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Wait until the mutex is unlocked. */
|
||||||
|
while (__ldrex(m) != MUTEX_UNLOCKED);
|
||||||
|
|
||||||
|
/* Try to acquire it. */
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
|
||||||
|
/* Did we get it? If not then try again. */
|
||||||
|
} while (status != 0);
|
||||||
|
|
||||||
|
/* Execute the mysterious Data Memory Barrier instruction! */
|
||||||
|
__dmb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_unlock(mutex_t *m)
|
||||||
|
{
|
||||||
|
/* Ensure accesses to protected resource are finished */
|
||||||
|
__dmb();
|
||||||
|
|
||||||
|
/* Free the lock. */
|
||||||
|
*m = MUTEX_UNLOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to lock mutex
|
||||||
|
* if it's already locked or there was error in STREX, return MUTEX_LOCKED
|
||||||
|
* else return MUTEX_UNLOCKED
|
||||||
|
*/
|
||||||
|
mutex_t mutex_trylock(mutex_t *m){
|
||||||
|
uint32_t status = 0;
|
||||||
|
mutex_t old_lock = __ldrex(m); // get mutex value
|
||||||
|
// set mutex
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
if(status == 0) __dmb();
|
||||||
|
else old_lock = MUTEX_LOCKED;
|
||||||
|
return old_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
53
F1/DMA_GPIO/sync.h
Normal file
53
F1/DMA_GPIO/sync.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBOPENCM3_CM3_SYNC_H
|
||||||
|
#define LIBOPENCM3_CM3_SYNC_H
|
||||||
|
|
||||||
|
void __dmb(void);
|
||||||
|
|
||||||
|
/* Implements synchronisation primitives as discussed in the ARM document
|
||||||
|
* DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M
|
||||||
|
* Architecture Reference Manual.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* --- Exclusive load and store instructions ------------------------------- */
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr);
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr);
|
||||||
|
|
||||||
|
/* --- Convenience functions ----------------------------------------------- */
|
||||||
|
|
||||||
|
/* Here we implement some simple synchronisation primitives. */
|
||||||
|
|
||||||
|
typedef uint32_t mutex_t;
|
||||||
|
|
||||||
|
#define MUTEX_UNLOCKED 0
|
||||||
|
#define MUTEX_LOCKED 1
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m);
|
||||||
|
void mutex_unlock(mutex_t *m);
|
||||||
|
mutex_t mutex_trylock(mutex_t *m);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
93
F1/DMA_GPIO/user_proto.c
Normal file
93
F1/DMA_GPIO/user_proto.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "dmagpio.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse command buffer buf with length len
|
||||||
|
* return 0 if buffer processed or len if there's not enough data in buffer
|
||||||
|
*/
|
||||||
|
void parse_incoming_buf(uint8_t *buf, int *len){
|
||||||
|
static int lastidx = 0;
|
||||||
|
int l = *len;
|
||||||
|
for(; lastidx < l; ++lastidx){
|
||||||
|
uint8_t cmd = buf[lastidx];
|
||||||
|
usb_send(cmd);
|
||||||
|
if(cmd == '\n'){
|
||||||
|
dmagpio_transfer(buf, *len);
|
||||||
|
*len = 0;
|
||||||
|
lastidx = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send char array wrd thru USB
|
||||||
|
*/
|
||||||
|
void prnt(uint8_t *wrd){
|
||||||
|
if(!wrd) return;
|
||||||
|
while(*wrd) usb_send(*wrd++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print buff as hex values
|
||||||
|
* @param buf - buffer to print
|
||||||
|
* @param l - buf length
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l){
|
||||||
|
void putc(uint8_t c){
|
||||||
|
if(c < 10)
|
||||||
|
usb_send(c + '0');
|
||||||
|
else
|
||||||
|
usb_send(c + 'a' - 10);
|
||||||
|
}
|
||||||
|
usb_send('0'); usb_send('x'); // prefix 0x
|
||||||
|
while(l--){
|
||||||
|
putc(buff[l] >> 4);
|
||||||
|
putc(buff[l] & 0x0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print decimal integer value
|
||||||
|
* @param N - value to print
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_int(int32_t N){
|
||||||
|
uint8_t buf[10], L = 0;
|
||||||
|
if(N < 0){
|
||||||
|
usb_send('-');
|
||||||
|
N = -N;
|
||||||
|
}
|
||||||
|
if(N){
|
||||||
|
while(N){
|
||||||
|
buf[L++] = N % 10 + '0';
|
||||||
|
N /= 10;
|
||||||
|
}
|
||||||
|
while(L--) usb_send(buf[L]);
|
||||||
|
}else usb_send('0');
|
||||||
|
}
|
||||||
|
|
||||||
47
F1/DMA_GPIO/user_proto.h
Normal file
47
F1/DMA_GPIO/user_proto.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __USER_PROTO_H__
|
||||||
|
#define __USER_PROTO_H__
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
|
||||||
|
// shorthand for prnt
|
||||||
|
#define P(arg) do{prnt((uint8_t*)arg);}while(0)
|
||||||
|
// debug message - over USB
|
||||||
|
#ifdef EBUG
|
||||||
|
#define DBG(a) do{prnt((uint8_t*)a);}while(0)
|
||||||
|
#else
|
||||||
|
#define DBG(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t (*intfun)(int32_t);
|
||||||
|
|
||||||
|
void prnt(uint8_t *wrd);
|
||||||
|
#define newline() usb_send('\n')
|
||||||
|
|
||||||
|
void print_int(int32_t N);
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l);
|
||||||
|
|
||||||
|
void parse_incoming_buf(uint8_t *buf, int *len);
|
||||||
|
|
||||||
|
#endif // __USER_PROTO_H__
|
||||||
133
F1/GPIO_TIM/Makefile
Normal file
133
F1/GPIO_TIM/Makefile
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
BINARY = tim_gpio
|
||||||
|
BOOTPORT ?= /dev/ttyUSB0
|
||||||
|
BOOTSPEED ?= 115200
|
||||||
|
# change this linking script depending on particular MCU model,
|
||||||
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
|
LDSCRIPT = ld/stm32f103x8.ld
|
||||||
|
LIBNAME = opencm3_stm32f1
|
||||||
|
DEFS = -DSTM32F1 -DEBUG
|
||||||
|
|
||||||
|
OBJDIR = mk
|
||||||
|
INDEPENDENT_HEADERS=
|
||||||
|
|
||||||
|
FP_FLAGS ?= -msoft-float
|
||||||
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Executables
|
||||||
|
PREFIX ?= arm-none-eabi
|
||||||
|
|
||||||
|
RM := rm -f
|
||||||
|
RMDIR := rmdir
|
||||||
|
CC := $(PREFIX)-gcc
|
||||||
|
LD := $(PREFIX)-gcc
|
||||||
|
AR := $(PREFIX)-ar
|
||||||
|
AS := $(PREFIX)-as
|
||||||
|
OBJCOPY := $(PREFIX)-objcopy
|
||||||
|
OBJDUMP := $(PREFIX)-objdump
|
||||||
|
GDB := $(PREFIX)-gdb
|
||||||
|
STFLASH = $(shell which st-flash)
|
||||||
|
STBOOT = $(shell which stm32flash)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Source files
|
||||||
|
LDSCRIPT ?= $(BINARY).ld
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||||
|
|
||||||
|
ifeq ($(strip $(OPENCM3_DIR)),)
|
||||||
|
OPENCM3_DIR := /usr/local/arm-none-eabi
|
||||||
|
$(info Using $(OPENCM3_DIR) path to library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
||||||
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
||||||
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C flags
|
||||||
|
CFLAGS += -Os -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
|
CFLAGS += -Wredundant-decls
|
||||||
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C & C++ preprocessor common flags
|
||||||
|
CPPFLAGS += -MD
|
||||||
|
CPPFLAGS += -Wall -Werror
|
||||||
|
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS += --static -nostartfiles
|
||||||
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
|
LDFLAGS += -Wl,-Map=$(*).map
|
||||||
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Used libraries
|
||||||
|
LDLIBS += -l$(LIBNAME)
|
||||||
|
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||||
|
|
||||||
|
.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
|
BIN := $(BINARY).bin
|
||||||
|
HEX := $(BINARY).hex
|
||||||
|
|
||||||
|
all: bin
|
||||||
|
|
||||||
|
elf: $(ELF)
|
||||||
|
bin: $(BIN)
|
||||||
|
hex: $(HEX)
|
||||||
|
list: $(LIST)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@printf " CC $<\n"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
%.h: ;
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@printf " OBJCOPY $(BIN)\n"
|
||||||
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|
||||||
|
$(HEX): $(ELF)
|
||||||
|
@printf " OBJCOPY $(HEX)\n"
|
||||||
|
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||||
|
|
||||||
|
$(LIST): $(ELF)
|
||||||
|
@printf " OBJDUMP $(LIST)\n"
|
||||||
|
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
|
||||||
|
@printf " LD $(ELF)\n"
|
||||||
|
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf " CLEAN\n"
|
||||||
|
$(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||||
|
$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
flash: $(BIN)
|
||||||
|
@printf " FLASH $(BIN)\n"
|
||||||
|
$(STFLASH) write $(BIN) 0x8000000
|
||||||
|
|
||||||
|
boot: $(BIN)
|
||||||
|
@printf " LOAD $(BIN) through bootloader\n"
|
||||||
|
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||||
|
|
||||||
|
.PHONY: clean elf hex list flash boot
|
||||||
|
|
||||||
|
#-include $(OBJS:.o=.d)
|
||||||
1
F1/GPIO_TIM/README
Normal file
1
F1/GPIO_TIM/README
Normal file
@ -0,0 +1 @@
|
|||||||
|
simple FSMC emulation by timer interrupts
|
||||||
310
F1/GPIO_TIM/cdcacm.c
Normal file
310
F1/GPIO_TIM/cdcacm.c
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
// Buffer for USB Tx
|
||||||
|
static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE];
|
||||||
|
static uint8_t USB_Tx_ptr = 0;
|
||||||
|
// connection flag
|
||||||
|
uint8_t USB_connected = 0;
|
||||||
|
static const struct usb_device_descriptor dev = {
|
||||||
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
.bDeviceClass = USB_CLASS_CDC,
|
||||||
|
.bDeviceSubClass = 0,
|
||||||
|
.bDeviceProtocol = 0,
|
||||||
|
.bMaxPacketSize0 = 64,
|
||||||
|
.idVendor = 0x0483,
|
||||||
|
.idProduct = 0x5740,
|
||||||
|
.bcdDevice = 0x0200,
|
||||||
|
.iManufacturer = 1,
|
||||||
|
.iProduct = 2,
|
||||||
|
.iSerialNumber = 3,
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data
|
||||||
|
int usbdatalen = 0; // lenght of received data
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This notification endpoint isn't implemented. According to CDC spec its
|
||||||
|
* optional, but its absence causes a NULL pointer dereference in Linux
|
||||||
|
* cdc_acm driver.
|
||||||
|
*/
|
||||||
|
static const struct usb_endpoint_descriptor comm_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x83,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
|
.wMaxPacketSize = 16,
|
||||||
|
.bInterval = 255,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_endpoint_descriptor data_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x01,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}, {
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x82,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
struct usb_cdc_header_descriptor header;
|
||||||
|
struct usb_cdc_call_management_descriptor call_mgmt;
|
||||||
|
struct usb_cdc_acm_descriptor acm;
|
||||||
|
struct usb_cdc_union_descriptor cdc_union;
|
||||||
|
} __attribute__((packed)) cdcacm_functional_descriptors = {
|
||||||
|
.header = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
|
||||||
|
.bcdCDC = 0x0110,
|
||||||
|
},
|
||||||
|
.call_mgmt = {
|
||||||
|
.bFunctionLength =
|
||||||
|
sizeof(struct usb_cdc_call_management_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
.bDataInterface = 1,
|
||||||
|
},
|
||||||
|
.acm = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
},
|
||||||
|
.cdc_union = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||||
|
.bControlInterface = 0,
|
||||||
|
.bSubordinateInterface0 = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor comm_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 0,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = comm_endp,
|
||||||
|
|
||||||
|
.extra = &cdcacm_functional_descriptors,
|
||||||
|
.extralen = sizeof(cdcacm_functional_descriptors),
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor data_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 2,
|
||||||
|
.bInterfaceClass = USB_CLASS_DATA,
|
||||||
|
.bInterfaceSubClass = 0,
|
||||||
|
.bInterfaceProtocol = 0,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = data_endp,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface ifaces[] = {{
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = comm_iface,
|
||||||
|
}, {
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = data_iface,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_config_descriptor config = {
|
||||||
|
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||||
|
.wTotalLength = 0,
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = 1,
|
||||||
|
.iConfiguration = 0,
|
||||||
|
.bmAttributes = 0x80,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
|
||||||
|
.interface = ifaces,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *usb_strings[] = {
|
||||||
|
"Organisation, author",
|
||||||
|
"device",
|
||||||
|
"version",
|
||||||
|
};
|
||||||
|
|
||||||
|
// default line coding: B115200, 1stop, 8bits, parity none
|
||||||
|
struct usb_cdc_line_coding linecoding = {
|
||||||
|
.dwDTERate = 115200,
|
||||||
|
.bCharFormat = USB_CDC_1_STOP_BITS,
|
||||||
|
.bParityType = USB_CDC_NO_PARITY,
|
||||||
|
.bDataBits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Buffer to be used for control requests. */
|
||||||
|
uint8_t usbd_control_buffer[128];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function runs every time it gets a request for control parameters get/set
|
||||||
|
* parameter SET_LINE_CODING used to change USART1 parameters: if you want to
|
||||||
|
* change them, just connect through USB with required parameters
|
||||||
|
*/
|
||||||
|
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
|
||||||
|
uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){
|
||||||
|
(void)complete;
|
||||||
|
(void)buf;
|
||||||
|
(void)usbd_dev;
|
||||||
|
char local_buf[10];
|
||||||
|
struct usb_cdc_line_coding lc;
|
||||||
|
|
||||||
|
switch (req->bRequest) {
|
||||||
|
case SET_CONTROL_LINE_STATE:{
|
||||||
|
if(req->wValue){ // terminal is opened
|
||||||
|
USB_connected = 1;
|
||||||
|
}else{ // terminal is closed
|
||||||
|
USB_connected = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This Linux cdc_acm driver requires this to be implemented
|
||||||
|
* even though it's optional in the CDC spec, and we don't
|
||||||
|
* advertise it in the ACM functional descriptor.
|
||||||
|
*/
|
||||||
|
struct usb_cdc_notification *notif = (void *)local_buf;
|
||||||
|
/* We echo signals back to host as notification. */
|
||||||
|
notif->bmRequestType = 0xA1;
|
||||||
|
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
|
||||||
|
notif->wValue = 0;
|
||||||
|
notif->wIndex = 0;
|
||||||
|
notif->wLength = 2;
|
||||||
|
local_buf[8] = req->wValue & 3;
|
||||||
|
local_buf[9] = 0;
|
||||||
|
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
|
||||||
|
}break;
|
||||||
|
case SET_LINE_CODING:
|
||||||
|
if (!len || (*len != sizeof(struct usb_cdc_line_coding)))
|
||||||
|
return 0;
|
||||||
|
memcpy((void *)&lc, (void *)*buf, *len);
|
||||||
|
// Mark & Space parity don't support by hardware, check it
|
||||||
|
if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){
|
||||||
|
return 0; // error
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_LINE_CODING: // return linecoding buffer
|
||||||
|
if(len && *len == sizeof(struct usb_cdc_line_coding))
|
||||||
|
memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen);
|
||||||
|
usbdatalen += len;
|
||||||
|
if(usbdatalen >= USB_RX_DATA_SIZE){ // buffer overflow - drop all its contents
|
||||||
|
usbdatalen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
|
||||||
|
{
|
||||||
|
(void)wValue;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
|
|
||||||
|
usbd_register_control_callback(
|
||||||
|
usbd_dev,
|
||||||
|
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||||
|
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||||
|
cdcacm_control_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbd_device *current_usb = NULL;
|
||||||
|
|
||||||
|
usbd_device *USB_init(){
|
||||||
|
current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config,
|
||||||
|
usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
if(!current_usb) return NULL;
|
||||||
|
usbd_register_set_config_callback(current_usb, cdcacm_set_config);
|
||||||
|
return current_usb;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_t send_block_mutex = MUTEX_UNLOCKED;
|
||||||
|
/**
|
||||||
|
* Put byte into USB buffer to send
|
||||||
|
* @param byte - a byte to put into a buffer
|
||||||
|
*/
|
||||||
|
void usb_send(uint8_t byte){
|
||||||
|
mutex_lock(&send_block_mutex);
|
||||||
|
USB_Tx_Buffer[USB_Tx_ptr++] = byte;
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it!
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send all data in buffer over USB
|
||||||
|
* this function runs when buffer is full or on SysTick
|
||||||
|
*/
|
||||||
|
void usb_send_buffer(){
|
||||||
|
if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return;
|
||||||
|
if(USB_Tx_ptr){
|
||||||
|
if(current_usb && USB_connected){
|
||||||
|
// usbd_ep_write_packet return 0 if previous packet isn't transmit yet
|
||||||
|
while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr));
|
||||||
|
usbd_poll(current_usb);
|
||||||
|
}
|
||||||
|
USB_Tx_ptr = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
}
|
||||||
54
F1/GPIO_TIM/cdcacm.h
Normal file
54
F1/GPIO_TIM/cdcacm.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ccdcacm.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __CCDCACM_H__
|
||||||
|
#define __CCDCACM_H__
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
|
// commands through EP0
|
||||||
|
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define GET_ENCAPSULATED_RESPONSE 0x01
|
||||||
|
#define SET_COMM_FEATURE 0x02
|
||||||
|
#define GET_COMM_FEATURE 0x03
|
||||||
|
#define CLEAR_COMM_FEATURE 0x04
|
||||||
|
#define SET_LINE_CODING 0x20
|
||||||
|
#define GET_LINE_CODING 0x21
|
||||||
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define SEND_BREAK 0x23
|
||||||
|
|
||||||
|
// Size of input/output buffers
|
||||||
|
#define USB_TX_DATA_SIZE 64
|
||||||
|
#define USB_RX_DATA_SIZE 64
|
||||||
|
|
||||||
|
// USB connection flag
|
||||||
|
extern uint8_t USB_connected;
|
||||||
|
extern struct usb_cdc_line_coding linecoding;
|
||||||
|
|
||||||
|
extern uint8_t usbdatabuf[];
|
||||||
|
extern int usbdatalen;
|
||||||
|
|
||||||
|
usbd_device *USB_init();
|
||||||
|
void usb_send(uint8_t byte);
|
||||||
|
void usb_send_buffer();
|
||||||
|
|
||||||
|
#endif // __CCDCACM_H__
|
||||||
60
F1/GPIO_TIM/hardware_ini.c
Normal file
60
F1/GPIO_TIM/hardware_ini.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.c - functions for HW initialisation
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All hardware-dependent initialisation & definition should be placed here
|
||||||
|
* and in hardware_ini.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO initialisaion: clocking + pins setup
|
||||||
|
*/
|
||||||
|
void GPIO_init(){
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
|
||||||
|
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN |
|
||||||
|
RCC_APB2ENR_IOPEEN);
|
||||||
|
// DMAGPIO
|
||||||
|
gpio_set_mode(DMAGPIO_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
|
||||||
|
DMAGPIO_PINS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// USB_DISC: push-pull
|
||||||
|
gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ,
|
||||||
|
GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN);
|
||||||
|
// USB_POWER: open drain, externall pull down with R7 (22k)
|
||||||
|
gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT,
|
||||||
|
GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SysTick used for system timer with period of 1ms
|
||||||
|
*/
|
||||||
|
void SysTick_init(){
|
||||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
||||||
|
systick_set_reload(8999); // 9000 pulses: 1kHz
|
||||||
|
systick_interrupt_enable();
|
||||||
|
systick_counter_enable();
|
||||||
|
}
|
||||||
65
F1/GPIO_TIM/hardware_ini.h
Normal file
65
F1/GPIO_TIM/hardware_ini.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __HARDWARE_INI_H__
|
||||||
|
#define __HARDWARE_INI_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timers:
|
||||||
|
* SysTick - system time
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void GPIO_init();
|
||||||
|
void SysTick_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA to GPIO port & pins (mask)
|
||||||
|
*/
|
||||||
|
#define DMAGPIO_PORT GPIOA
|
||||||
|
#define DMAGPIO_PINS 0xff
|
||||||
|
#define DMAGPIO_TARGADDR GPIOA_ODR
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB interface
|
||||||
|
* connect boot1 jumper to gnd, boot0 to gnd; and reconnect boot0 to +3.3 to boot flash
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
// USB_DICS (disconnect) - PC11
|
||||||
|
#define USB_DISC_PIN GPIO11
|
||||||
|
#define USB_DISC_PORT GPIOC
|
||||||
|
// USB_POWER (high level when USB connected to PC)
|
||||||
|
#define USB_POWER_PIN GPIO10
|
||||||
|
#define USB_POWER_PORT GPIOC
|
||||||
|
// change signal level on USB diconnect pin
|
||||||
|
#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level
|
||||||
|
// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level
|
||||||
|
#define usb_disconnect() usb_disc_high()
|
||||||
|
#define usb_connect() usb_disc_low()
|
||||||
|
*/
|
||||||
|
// my simple devboard have no variants for programmed connection/disconnection of USB
|
||||||
|
#define usb_disconnect()
|
||||||
|
#define usb_connect()
|
||||||
|
|
||||||
|
#endif // __HARDWARE_INI_H__
|
||||||
9
F1/GPIO_TIM/ld/devices.data
Normal file
9
F1/GPIO_TIM/ld/devices.data
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
stm32f103?4* stm32f1 ROM=16K RAM=6K
|
||||||
|
stm32f103?6* stm32f1 ROM=32K RAM=10K
|
||||||
|
stm32f103?8* stm32f1 ROM=64K RAM=20K
|
||||||
|
stm32f103?b* stm32f1 ROM=128K RAM=20K
|
||||||
|
stm32f103?c* stm32f1 ROM=256K RAM=48K
|
||||||
|
stm32f103?d* stm32f1 ROM=384K RAM=64K
|
||||||
|
stm32f103?e* stm32f1 ROM=512K RAM=64K
|
||||||
|
stm32f103?f* stm32f1 ROM=768K RAM=96K
|
||||||
|
stm32f103?g* stm32f1 ROM=1024K RAM=96K
|
||||||
31
F1/GPIO_TIM/ld/stm32f103x4.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103x4.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103x6.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103x6.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103x8.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103x8.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xB.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xB.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xC.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xC.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xD.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xD.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xE.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xE.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xF.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xF.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPIO_TIM/ld/stm32f103xG.ld
Normal file
31
F1/GPIO_TIM/ld/stm32f103xG.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
90
F1/GPIO_TIM/main.c
Normal file
90
F1/GPIO_TIM/main.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "timgpio.h"
|
||||||
|
|
||||||
|
volatile uint32_t Timer = 0; // global timer (milliseconds)
|
||||||
|
usbd_device *usbd_dev;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
uint32_t Old_timer = 0;
|
||||||
|
|
||||||
|
// RCC clocking: 8MHz oscillator -> 72MHz system
|
||||||
|
rcc_clock_setup_in_hse_8mhz_out_72mhz();
|
||||||
|
|
||||||
|
GPIO_init();
|
||||||
|
|
||||||
|
usb_disconnect(); // turn off USB while initializing all
|
||||||
|
|
||||||
|
// USB
|
||||||
|
usbd_dev = USB_init();
|
||||||
|
|
||||||
|
// SysTick is a system timer with 1ms period
|
||||||
|
SysTick_init();
|
||||||
|
timgpio_init();
|
||||||
|
|
||||||
|
usb_connect(); // turn on USB
|
||||||
|
|
||||||
|
int oldusblen = 0;
|
||||||
|
while(1){
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
if(usbdatalen != oldusblen){ // there's something in USB buffer
|
||||||
|
parse_incoming_buf(usbdatabuf, &usbdatalen);
|
||||||
|
oldusblen = usbdatalen;
|
||||||
|
}
|
||||||
|
if(transfer_complete){
|
||||||
|
P("transfered\n");
|
||||||
|
transfer_complete = 0;
|
||||||
|
}
|
||||||
|
if(Timer - Old_timer > 999){ // one-second cycle
|
||||||
|
Old_timer += 1000;
|
||||||
|
}else if(Timer < Old_timer){ // Timer overflow
|
||||||
|
Old_timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SysTick interrupt: increment global time & send data buffer through USB
|
||||||
|
*/
|
||||||
|
void sys_tick_handler(){
|
||||||
|
Timer++;
|
||||||
|
usbd_poll(usbd_dev);
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// pause function, delay in ms
|
||||||
|
void Delay(uint16_t _U_ time){
|
||||||
|
uint32_t waitto = Timer + time;
|
||||||
|
while(Timer < waitto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print current time in milliseconds: 4 bytes for ovrvlow + 4 bytes for time
|
||||||
|
* with ' ' as delimeter
|
||||||
|
*/
|
||||||
|
void print_time(){
|
||||||
|
print_int(Timer);
|
||||||
|
}
|
||||||
53
F1/GPIO_TIM/main.h
Normal file
53
F1/GPIO_TIM/main.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* main.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MAIN_H__
|
||||||
|
#define __MAIN_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
#include <libopencm3/stm32/gpio.h>
|
||||||
|
#include <libopencm3/stm32/usart.h>
|
||||||
|
#include <libopencm3/cm3/nvic.h>
|
||||||
|
#include <libopencm3/usb/cdc.h>
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
#include <libopencm3/cm3/systick.h>
|
||||||
|
#include <libopencm3/stm32/rcc.h>
|
||||||
|
#include <libopencm3/stm32/adc.h>
|
||||||
|
#include <libopencm3/stm32/dma.h>
|
||||||
|
#include <libopencm3/stm32/spi.h>
|
||||||
|
#include <libopencm3/stm32/timer.h>
|
||||||
|
|
||||||
|
#include "sync.h" // mutexes
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
#define _U_ __attribute__((__unused__))
|
||||||
|
#define U8(x) ((uint8_t) x)
|
||||||
|
#define U16(x) ((uint16_t) x)
|
||||||
|
#define U32(x) ((uint32_t) x)
|
||||||
|
|
||||||
|
extern volatile uint32_t Timer; // global timer (milliseconds)
|
||||||
|
void Delay(uint16_t time);
|
||||||
|
|
||||||
|
#endif // __MAIN_H__
|
||||||
|
|
||||||
93
F1/GPIO_TIM/sync.c
Normal file
93
F1/GPIO_TIM/sync.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* implement mutexes for other type of MCU (which doesn't have strex & ldrex)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libopencm3/cm3/sync.h>
|
||||||
|
|
||||||
|
/* DMB is supported on CM0 */
|
||||||
|
void __dmb()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("dmb");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm__ volatile ("strex %0, %2, [%1]"
|
||||||
|
: "=&r" (res) : "r" (addr), "r" (val));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m)
|
||||||
|
{
|
||||||
|
uint32_t status = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Wait until the mutex is unlocked. */
|
||||||
|
while (__ldrex(m) != MUTEX_UNLOCKED);
|
||||||
|
|
||||||
|
/* Try to acquire it. */
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
|
||||||
|
/* Did we get it? If not then try again. */
|
||||||
|
} while (status != 0);
|
||||||
|
|
||||||
|
/* Execute the mysterious Data Memory Barrier instruction! */
|
||||||
|
__dmb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mutex_unlock(mutex_t *m)
|
||||||
|
{
|
||||||
|
/* Ensure accesses to protected resource are finished */
|
||||||
|
__dmb();
|
||||||
|
|
||||||
|
/* Free the lock. */
|
||||||
|
*m = MUTEX_UNLOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to lock mutex
|
||||||
|
* if it's already locked or there was error in STREX, return MUTEX_LOCKED
|
||||||
|
* else return MUTEX_UNLOCKED
|
||||||
|
*/
|
||||||
|
mutex_t mutex_trylock(mutex_t *m){
|
||||||
|
uint32_t status = 0;
|
||||||
|
mutex_t old_lock = __ldrex(m); // get mutex value
|
||||||
|
// set mutex
|
||||||
|
status = __strex(MUTEX_LOCKED, m);
|
||||||
|
if(status == 0) __dmb();
|
||||||
|
else old_lock = MUTEX_LOCKED;
|
||||||
|
return old_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
53
F1/GPIO_TIM/sync.h
Normal file
53
F1/GPIO_TIM/sync.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBOPENCM3_CM3_SYNC_H
|
||||||
|
#define LIBOPENCM3_CM3_SYNC_H
|
||||||
|
|
||||||
|
void __dmb(void);
|
||||||
|
|
||||||
|
/* Implements synchronisation primitives as discussed in the ARM document
|
||||||
|
* DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M
|
||||||
|
* Architecture Reference Manual.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* --- Exclusive load and store instructions ------------------------------- */
|
||||||
|
|
||||||
|
/* Those are defined only on CM3 or CM4 */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
|
|
||||||
|
uint32_t __ldrex(volatile uint32_t *addr);
|
||||||
|
uint32_t __strex(uint32_t val, volatile uint32_t *addr);
|
||||||
|
|
||||||
|
/* --- Convenience functions ----------------------------------------------- */
|
||||||
|
|
||||||
|
/* Here we implement some simple synchronisation primitives. */
|
||||||
|
|
||||||
|
typedef uint32_t mutex_t;
|
||||||
|
|
||||||
|
#define MUTEX_UNLOCKED 0
|
||||||
|
#define MUTEX_LOCKED 1
|
||||||
|
|
||||||
|
void mutex_lock(mutex_t *m);
|
||||||
|
void mutex_unlock(mutex_t *m);
|
||||||
|
mutex_t mutex_trylock(mutex_t *m);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
F1/GPIO_TIM/tim_gpio.bin
Executable file
BIN
F1/GPIO_TIM/tim_gpio.bin
Executable file
Binary file not shown.
61
F1/GPIO_TIM/timgpio.c
Normal file
61
F1/GPIO_TIM/timgpio.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* timgpio.c
|
||||||
|
*
|
||||||
|
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timgpio.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
|
||||||
|
int transfer_complete = 0;
|
||||||
|
static uint8_t addr[128];
|
||||||
|
static uint32_t len = 0, curidx = 0;
|
||||||
|
|
||||||
|
void timgpio_init(){
|
||||||
|
// init TIM2 & DMA1ch2 (TIM2UP)
|
||||||
|
rcc_periph_clock_enable(RCC_TIM2);
|
||||||
|
rcc_periph_clock_enable(RCC_DMA1);
|
||||||
|
timer_reset(TIM2);
|
||||||
|
// timer have frequency of 1MHz
|
||||||
|
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
|
||||||
|
// 72MHz main freq, 2MHz for timer
|
||||||
|
TIM2_PSC = 0;
|
||||||
|
TIM2_ARR = 35;
|
||||||
|
TIM2_DIER = TIM_DIER_UDE | TIM_DIER_UIE;
|
||||||
|
nvic_enable_irq(NVIC_TIM2_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tim2_isr(){
|
||||||
|
if(TIM2_SR & TIM_SR_UIF){ // update interrupt
|
||||||
|
GPIOA_ODR = addr[curidx];
|
||||||
|
if(++curidx >= len){
|
||||||
|
TIM2_CR1 &= ~TIM_CR1_CEN;
|
||||||
|
transfer_complete = 1;
|
||||||
|
}
|
||||||
|
TIM2_SR = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timgpio_transfer(uint8_t *databuf, uint32_t length){
|
||||||
|
transfer_complete = 0;
|
||||||
|
memcpy(addr, databuf, length);
|
||||||
|
len = length;
|
||||||
|
curidx = 0;
|
||||||
|
TIM2_CR1 |= TIM_CR1_CEN; // run timer
|
||||||
|
}
|
||||||
32
F1/GPIO_TIM/timgpio.h
Normal file
32
F1/GPIO_TIM/timgpio.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* timpio.h
|
||||||
|
*
|
||||||
|
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef __DMAGPIO_H__
|
||||||
|
#define __DMAGPIO_H__
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
void timgpio_init();
|
||||||
|
void timgpio_transfer(uint8_t *databuf, uint32_t length);
|
||||||
|
extern int transfer_complete;
|
||||||
|
|
||||||
|
#endif // __DMAGPIO_H__
|
||||||
93
F1/GPIO_TIM/user_proto.c
Normal file
93
F1/GPIO_TIM/user_proto.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
#include "timgpio.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse command buffer buf with length len
|
||||||
|
* return 0 if buffer processed or len if there's not enough data in buffer
|
||||||
|
*/
|
||||||
|
void parse_incoming_buf(uint8_t *buf, int *len){
|
||||||
|
static int lastidx = 0;
|
||||||
|
int l = *len;
|
||||||
|
for(; lastidx < l; ++lastidx){
|
||||||
|
uint8_t cmd = buf[lastidx];
|
||||||
|
usb_send(cmd);
|
||||||
|
if(cmd == '\n'){
|
||||||
|
timgpio_transfer(buf, *len);
|
||||||
|
*len = 0;
|
||||||
|
lastidx = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send char array wrd thru USB
|
||||||
|
*/
|
||||||
|
void prnt(uint8_t *wrd){
|
||||||
|
if(!wrd) return;
|
||||||
|
while(*wrd) usb_send(*wrd++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print buff as hex values
|
||||||
|
* @param buf - buffer to print
|
||||||
|
* @param l - buf length
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l){
|
||||||
|
void putc(uint8_t c){
|
||||||
|
if(c < 10)
|
||||||
|
usb_send(c + '0');
|
||||||
|
else
|
||||||
|
usb_send(c + 'a' - 10);
|
||||||
|
}
|
||||||
|
usb_send('0'); usb_send('x'); // prefix 0x
|
||||||
|
while(l--){
|
||||||
|
putc(buff[l] >> 4);
|
||||||
|
putc(buff[l] & 0x0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print decimal integer value
|
||||||
|
* @param N - value to print
|
||||||
|
* @param s - function to send a byte
|
||||||
|
*/
|
||||||
|
void print_int(int32_t N){
|
||||||
|
uint8_t buf[10], L = 0;
|
||||||
|
if(N < 0){
|
||||||
|
usb_send('-');
|
||||||
|
N = -N;
|
||||||
|
}
|
||||||
|
if(N){
|
||||||
|
while(N){
|
||||||
|
buf[L++] = N % 10 + '0';
|
||||||
|
N /= 10;
|
||||||
|
}
|
||||||
|
while(L--) usb_send(buf[L]);
|
||||||
|
}else usb_send('0');
|
||||||
|
}
|
||||||
|
|
||||||
47
F1/GPIO_TIM/user_proto.h
Normal file
47
F1/GPIO_TIM/user_proto.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* user_proto.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __USER_PROTO_H__
|
||||||
|
#define __USER_PROTO_H__
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
|
||||||
|
// shorthand for prnt
|
||||||
|
#define P(arg) do{prnt((uint8_t*)arg);}while(0)
|
||||||
|
// debug message - over USB
|
||||||
|
#ifdef EBUG
|
||||||
|
#define DBG(a) do{prnt((uint8_t*)a);}while(0)
|
||||||
|
#else
|
||||||
|
#define DBG(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t (*intfun)(int32_t);
|
||||||
|
|
||||||
|
void prnt(uint8_t *wrd);
|
||||||
|
#define newline() usb_send('\n')
|
||||||
|
|
||||||
|
void print_int(int32_t N);
|
||||||
|
void print_hex(uint8_t *buff, uint8_t l);
|
||||||
|
|
||||||
|
void parse_incoming_buf(uint8_t *buf, int *len);
|
||||||
|
|
||||||
|
#endif // __USER_PROTO_H__
|
||||||
263
F1/GPS+ultrasonic/GPS.c
Normal file
263
F1/GPS+ultrasonic/GPS.c
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* GPS.c
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "GPS.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#define GPS_endline() do{GPS_send_string((uint8_t*)"\r\n");}while(0)
|
||||||
|
#define U(arg) ((uint8_t*)arg)
|
||||||
|
|
||||||
|
gps_status GPS_status = GPS_WAIT;
|
||||||
|
|
||||||
|
void GPS_send_string(uint8_t *str){
|
||||||
|
while(*str)
|
||||||
|
fill_uart_buff(USART2, *str++);
|
||||||
|
}
|
||||||
|
|
||||||
|
int strncmp(const uint8_t *one, const uint8_t *two, int n){
|
||||||
|
int diff = 0;
|
||||||
|
do{
|
||||||
|
diff = (int)(*one++) - (int)(*two++);
|
||||||
|
}while(--n && diff == 0);
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ustrchr(uint8_t *str, uint8_t symbol){
|
||||||
|
// uint8_t *ptr = str;
|
||||||
|
do{
|
||||||
|
if(*str == symbol) return str;
|
||||||
|
}while(*(++str));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hex(uint8_t n){
|
||||||
|
return ((n < 10) ? (n+'0') : (n+'A'-10));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check checksum
|
||||||
|
*/
|
||||||
|
int checksum_true(uint8_t *buf){
|
||||||
|
uint8_t *eol;
|
||||||
|
uint8_t checksum = 0, cs[3];
|
||||||
|
if(*buf != '$' || !(eol = ustrchr(buf, '*'))){
|
||||||
|
DBG("Wrong data: ");
|
||||||
|
DBG(buf);
|
||||||
|
DBG("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while(++buf != eol)
|
||||||
|
checksum ^= *buf;
|
||||||
|
++buf;
|
||||||
|
cs[0] = hex(checksum >> 4);
|
||||||
|
cs[1] = hex(checksum & 0x0f);
|
||||||
|
if(buf[0] == cs[0] && buf[1] == cs[1])
|
||||||
|
return 1;
|
||||||
|
#ifdef EBUG
|
||||||
|
cs[2] = 0;
|
||||||
|
P("CHS, get ");
|
||||||
|
P(buf);
|
||||||
|
P(" need ");
|
||||||
|
P(cs);
|
||||||
|
usb_send('\n');
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_chksum(uint8_t chs){
|
||||||
|
fill_uart_buff(USART2, hex(chs >> 4));
|
||||||
|
fill_uart_buff(USART2, hex(chs & 0x0f));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Calculate checksum & write message to port
|
||||||
|
* @param buf - command to write (with leading $ and trailing *)
|
||||||
|
* return 0 if fails
|
||||||
|
*/
|
||||||
|
void write_with_checksum(uint8_t *buf){
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
GPS_send_string(buf);
|
||||||
|
++buf; // skip leaders
|
||||||
|
do{
|
||||||
|
checksum ^= *buf++;
|
||||||
|
}while(*buf && *buf != '*');
|
||||||
|
send_chksum(checksum);
|
||||||
|
GPS_endline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set rate for given NMEA field
|
||||||
|
* @param field - name of NMEA field
|
||||||
|
* @param rate - rate in seconds (0 disables field)
|
||||||
|
* @return -1 if fails, rate if OK
|
||||||
|
*/
|
||||||
|
void block_field(const uint8_t *field){
|
||||||
|
uint8_t buf[22];
|
||||||
|
memcpy(buf, U("$PUBX,40,"), 9);
|
||||||
|
memcpy(buf+9, field, 3);
|
||||||
|
memcpy(buf+12, U(",0,0,0,0*"), 9);
|
||||||
|
buf[21] = 0;
|
||||||
|
write_with_checksum(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send starting sequences (get only RMC messages)
|
||||||
|
*/
|
||||||
|
void GPS_send_start_seq(){
|
||||||
|
const uint8_t *GPmsgs[5] = {U("GSV"), U("GSA"), U("GGA"), U("GLL"), U("VTG")};
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 5; ++i)
|
||||||
|
block_field(GPmsgs[i]);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
uint8_t *nextpos(uint8_t **buf, int pos){
|
||||||
|
int i;
|
||||||
|
if(pos < 1) pos = 1;
|
||||||
|
for(i = 0; i < pos; ++i){
|
||||||
|
*buf = ustrchr(*buf, ',');
|
||||||
|
if(!*buf) break;
|
||||||
|
++(*buf);
|
||||||
|
}
|
||||||
|
return *buf;
|
||||||
|
}
|
||||||
|
#define NEXT() do{if(!nextpos(&buf, 1)) goto ret;}while(0)
|
||||||
|
#define SKIP(NPOS) do{if(!nextpos(&buf, NPOS)) goto ret;}while(0)
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Parse answer from GPS module
|
||||||
|
*
|
||||||
|
* Recommended minimum specific GPS/Transit data
|
||||||
|
* $GPRMC,hhmmss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs
|
||||||
|
* 1 = UTC of position fix
|
||||||
|
* 2 = Data status (V=navigation receiver warning)
|
||||||
|
* 3 = Latitude of fix
|
||||||
|
* 4 = N or S
|
||||||
|
* 5 = Longitude of fix
|
||||||
|
* 6 = E or W
|
||||||
|
* 7 = Speed over ground in knots
|
||||||
|
* 8 = Cource over ground in degrees
|
||||||
|
* 9 = UT date
|
||||||
|
* 10 = Magnetic variation degrees (Easterly var. subtracts from true course)
|
||||||
|
* 11 = E or W
|
||||||
|
* 12 = Mode: N(bad), E(approx), A(auto), D(diff)
|
||||||
|
* 213457.00,A,4340.59415,N,04127.47560,E,2.494,,290615,,,A*7B
|
||||||
|
*/
|
||||||
|
void GPS_parse_answer(uint8_t *buf){
|
||||||
|
uint8_t *ptr;
|
||||||
|
if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message
|
||||||
|
GPS_send_start_seq();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!checksum_true(buf)){
|
||||||
|
DBG("Wrong chs\n");
|
||||||
|
return; // wrong checksum
|
||||||
|
}
|
||||||
|
buf += 7; // skip header
|
||||||
|
if(*buf == ','){ // time unknown
|
||||||
|
GPS_status = GPS_WAIT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//P("time: ");
|
||||||
|
ptr = ustrchr(buf, ',');
|
||||||
|
*ptr++ = 0;
|
||||||
|
//P(buf);
|
||||||
|
if(*ptr == 'A'){
|
||||||
|
GPS_status = GPS_VALID;
|
||||||
|
set_time(buf);
|
||||||
|
}else
|
||||||
|
GPS_status = GPS_NOT_VALID;
|
||||||
|
// buf = ustrchr(ptr, ',');
|
||||||
|
// P(" ");
|
||||||
|
// P("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
void rmc(uint8_t *buf){
|
||||||
|
//DBG("rmc: %s\n", buf);
|
||||||
|
int H, M, LO, LA, d, m, y, getdate = 0;
|
||||||
|
double S, longitude, lattitude, speed, track, mag;
|
||||||
|
char varn = 'V', north = '0', east = '0', mageast = '0', mode = 'N';
|
||||||
|
sscanf((char*)buf, "%2d%2d%lf", &H, &M, &S);
|
||||||
|
NEXT();
|
||||||
|
if(*buf != ',') varn = *buf;
|
||||||
|
if(varn != 'A')
|
||||||
|
PRINT("(data could be wrong)");
|
||||||
|
else{
|
||||||
|
PRINT("(data valid)");
|
||||||
|
if(GP->date) getdate = 1; // as only we have valid data we show it to user
|
||||||
|
}
|
||||||
|
PRINT(" time: %02d:%02d:%05.2f", H, M, S);
|
||||||
|
PRINT(" timediff: %g", timediff(H, M, S));
|
||||||
|
NEXT();
|
||||||
|
sscanf((char*)buf, "%2d%lf", &LA, &lattitude);
|
||||||
|
NEXT();
|
||||||
|
if(*buf != ','){
|
||||||
|
north = *buf;
|
||||||
|
lattitude = (double)LA + lattitude / 60.;
|
||||||
|
if(north == 'S') lattitude = -lattitude;
|
||||||
|
PRINT(" latt: %g", lattitude);
|
||||||
|
Latt_mean += lattitude;
|
||||||
|
Latt_sq += lattitude*lattitude;
|
||||||
|
++Latt_N;
|
||||||
|
}
|
||||||
|
NEXT();
|
||||||
|
sscanf((char*)buf, "%3d%lf", &LO, &longitude);
|
||||||
|
NEXT();
|
||||||
|
if(*buf != ','){
|
||||||
|
east = *buf;
|
||||||
|
longitude = (double)LO + longitude / 60.;
|
||||||
|
if(east == 'W') longitude = -longitude;
|
||||||
|
PRINT(" long: %g", longitude);
|
||||||
|
Long_mean += longitude;
|
||||||
|
Long_sq += longitude*longitude;
|
||||||
|
++Long_N;
|
||||||
|
}
|
||||||
|
NEXT();
|
||||||
|
if(*buf != ','){
|
||||||
|
sscanf((char*)buf, "%lf", &speed);
|
||||||
|
PRINT(" speed: %gknots", speed);
|
||||||
|
}
|
||||||
|
NEXT();
|
||||||
|
if(*buf != ','){
|
||||||
|
sscanf((char*)buf, "%lf", &track);
|
||||||
|
PRINT(" track: %gdeg,True", track);
|
||||||
|
}
|
||||||
|
NEXT();
|
||||||
|
if(sscanf((char*)buf, "%2d%2d%2d", &d, &m, &y) == 3)
|
||||||
|
PRINT(" date(dd/mm/yy): %02d/%02d/%02d", d, m, y);
|
||||||
|
if(getdate) show_date(H,M,S,d,m,y); // show date & exit
|
||||||
|
NEXT();
|
||||||
|
sscanf((char*)buf, "%lf,%c", &mag, &mageast);
|
||||||
|
if(mageast == 'E' || mageast == 'W'){
|
||||||
|
if(mageast == 'W') mag = -mag;
|
||||||
|
PRINT(" magnetic var: %g", mag);
|
||||||
|
}
|
||||||
|
SKIP(2);
|
||||||
|
if(*buf != ','){
|
||||||
|
mode = *buf;
|
||||||
|
PRINT(" mode: %c", mode);
|
||||||
|
}
|
||||||
|
ret:
|
||||||
|
PRINT("\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
37
F1/GPS+ultrasonic/GPS.h
Normal file
37
F1/GPS+ultrasonic/GPS.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* GPS.h
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __GPS_H__
|
||||||
|
#define __GPS_H__
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
GPS_WAIT // wait for satellites
|
||||||
|
,GPS_NOT_VALID // time known, but not valid
|
||||||
|
,GPS_VALID
|
||||||
|
} gps_status;
|
||||||
|
|
||||||
|
extern gps_status GPS_status;
|
||||||
|
|
||||||
|
void GPS_parse_answer(uint8_t *string);
|
||||||
|
void GPS_send_start_seq();
|
||||||
|
|
||||||
|
#endif // __GPS_H__
|
||||||
133
F1/GPS+ultrasonic/Makefile
Normal file
133
F1/GPS+ultrasonic/Makefile
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
BINARY = timelapse
|
||||||
|
BOOTPORT ?= /dev/ttyUSB0
|
||||||
|
BOOTSPEED ?= 115200
|
||||||
|
# change this linking script depending on particular MCU model,
|
||||||
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
|
LDSCRIPT = ld/stm32f103x8.ld
|
||||||
|
LIBNAME = opencm3_stm32f1
|
||||||
|
DEFS = -DSTM32F1 -DEBUG
|
||||||
|
|
||||||
|
OBJDIR = mk
|
||||||
|
INDEPENDENT_HEADERS=
|
||||||
|
|
||||||
|
FP_FLAGS ?= -msoft-float
|
||||||
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Executables
|
||||||
|
PREFIX ?= arm-none-eabi
|
||||||
|
|
||||||
|
RM := rm -f
|
||||||
|
RMDIR := rmdir
|
||||||
|
CC := $(PREFIX)-gcc
|
||||||
|
LD := $(PREFIX)-gcc
|
||||||
|
AR := $(PREFIX)-ar
|
||||||
|
AS := $(PREFIX)-as
|
||||||
|
OBJCOPY := $(PREFIX)-objcopy
|
||||||
|
OBJDUMP := $(PREFIX)-objdump
|
||||||
|
GDB := $(PREFIX)-gdb
|
||||||
|
STFLASH = $(shell which st-flash)
|
||||||
|
STBOOT = $(shell which stm32flash)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Source files
|
||||||
|
LDSCRIPT ?= $(BINARY).ld
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
|
||||||
|
|
||||||
|
ifeq ($(strip $(OPENCM3_DIR)),)
|
||||||
|
OPENCM3_DIR := /usr/local/arm-none-eabi
|
||||||
|
$(info Using $(OPENCM3_DIR) path to library)
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
||||||
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
||||||
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C flags
|
||||||
|
CFLAGS += -Os -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration
|
||||||
|
CFLAGS += -Wredundant-decls
|
||||||
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# C & C++ preprocessor common flags
|
||||||
|
CPPFLAGS += -MD
|
||||||
|
CPPFLAGS += -Wall -Werror
|
||||||
|
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS += --static -nostartfiles
|
||||||
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
|
LDFLAGS += -Wl,-Map=$(*).map
|
||||||
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Used libraries
|
||||||
|
LDLIBS += -l$(LIBNAME)
|
||||||
|
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||||
|
|
||||||
|
.SUFFIXES: .elf .bin .hex .srec .list .map .images
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
ELF := $(OBJDIR)/$(BINARY).elf
|
||||||
|
LIST := $(OBJDIR)/$(BINARY).list
|
||||||
|
BIN := $(BINARY).bin
|
||||||
|
HEX := $(BINARY).hex
|
||||||
|
|
||||||
|
all: bin
|
||||||
|
|
||||||
|
elf: $(ELF)
|
||||||
|
bin: $(BIN)
|
||||||
|
hex: $(HEX)
|
||||||
|
list: $(LIST)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@printf " CC $<\n"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
%.h: ;
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@printf " OBJCOPY $(BIN)\n"
|
||||||
|
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||||
|
|
||||||
|
$(HEX): $(ELF)
|
||||||
|
@printf " OBJCOPY $(HEX)\n"
|
||||||
|
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||||
|
|
||||||
|
$(LIST): $(ELF)
|
||||||
|
@printf " OBJDUMP $(LIST)\n"
|
||||||
|
$(OBJDUMP) -S $(ELF) > $(LIST)
|
||||||
|
|
||||||
|
$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
|
||||||
|
@printf " LD $(ELF)\n"
|
||||||
|
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@printf " CLEAN\n"
|
||||||
|
$(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map
|
||||||
|
$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
flash: $(BIN)
|
||||||
|
@printf " FLASH $(BIN)\n"
|
||||||
|
$(STFLASH) write $(BIN) 0x8000000
|
||||||
|
|
||||||
|
boot: $(BIN)
|
||||||
|
@printf " LOAD $(BIN) through bootloader\n"
|
||||||
|
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
|
||||||
|
|
||||||
|
.PHONY: clean elf hex list flash boot
|
||||||
|
|
||||||
|
#-include $(OBJS:.o=.d)
|
||||||
8
F1/GPS+ultrasonic/README
Normal file
8
F1/GPS+ultrasonic/README
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
GPS-based timelapse tool
|
||||||
|
Connect up to four sensors (ultrasonic, infrared, laser and simple switch)
|
||||||
|
and get precision (milliseconds) time of their signals
|
||||||
|
|
||||||
|
written for chinese devboard based on STM32F103RBT6
|
||||||
|
|
||||||
|
Press H for help
|
||||||
|
|
||||||
140
F1/GPS+ultrasonic/adc.c
Normal file
140
F1/GPS+ultrasonic/adc.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* adc.c - functions for Sharp 2Y0A02 distance meter & photosensor
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "adc.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
uint16_t ADC_value[ADC_CHANNEL_NUMBER]; // Values of ADC
|
||||||
|
uint16_t ADC_trig_val[ADC_CHANNEL_NUMBER]; // -//- at trigger time
|
||||||
|
|
||||||
|
void init_adc_sensor(){
|
||||||
|
// we will use ADC1 channel 0 for IR sensor & ADC1 channel 1 for laser's photoresistor
|
||||||
|
uint8_t adc_channel_array[ADC_CHANNEL_NUMBER] = {0,1};
|
||||||
|
// Make sure the ADC doesn't run during config
|
||||||
|
adc_off(ADC1);
|
||||||
|
// enable ADC & PA0/PA1 clocking
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN | RCC_APB2ENR_IOPAEN);
|
||||||
|
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4);
|
||||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0 | GPIO1);
|
||||||
|
rcc_periph_clock_enable(RCC_DMA1); // enable DMA for ADC values storing
|
||||||
|
// Configure ADC as continuous scan mode with DMA
|
||||||
|
ADC1_CR1 = ADC_CR1_SCAN; // enable scan mode
|
||||||
|
// set sample time on channels 1&2: 239.5 cycles for better results
|
||||||
|
ADC1_SMPR2 = 0x3f;
|
||||||
|
dma_channel_reset(DMA1, DMA_CHANNEL1);
|
||||||
|
DMA1_CPAR1 = (uint32_t) &(ADC_DR(ADC1));
|
||||||
|
DMA1_CMAR1 = (uint32_t) ADC_value;
|
||||||
|
DMA1_CNDTR1 = ADC_CHANNEL_NUMBER;
|
||||||
|
DMA1_CCR1 = DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT
|
||||||
|
| DMA_CCR_CIRC | DMA_CCR_PL_HIGH | DMA_CCR_EN;
|
||||||
|
// continuous conv, enable ADC & DMA
|
||||||
|
ADC1_CR2 = ADC_CR2_CONT | ADC_CR2_ADON | ADC_CR2_DMA;
|
||||||
|
// set channels
|
||||||
|
adc_set_regular_sequence(ADC1, ADC_CHANNEL_NUMBER, adc_channel_array);
|
||||||
|
// reset calibration registers & start calibration
|
||||||
|
ADC1_CR2 |= ADC_CR2_RSTCAL;
|
||||||
|
while(ADC1_CR2 & ADC_CR2_RSTCAL); // wait for registers reset
|
||||||
|
ADC1_CR2 |= ADC_CR2_CAL;
|
||||||
|
while(ADC1_CR2 & ADC_CR2_CAL); // wait for calibration ends
|
||||||
|
// set threshold limits
|
||||||
|
// ADC1_HTR = ADC_WDG_HIGH;
|
||||||
|
// ADC1_LTR = ADC_WDG_LOW;
|
||||||
|
// enable analog watchdog on single regular channel 0 & enable interrupt
|
||||||
|
//ADC1_CR1 = ADC_CR1_AWDEN | ADC_CR1_AWDSGL | ADC_CR1_AWDIE;
|
||||||
|
// enable analog watchdog on all regular channels & enable interrupt
|
||||||
|
// ADC1_CR1 |= ADC_CR1_AWDEN | ADC_CR1_AWDIE;
|
||||||
|
nvic_enable_irq(NVIC_ADC1_2_IRQ);
|
||||||
|
ADC1_CR2 |= ADC_CR2_SWSTART;
|
||||||
|
// turn on ADC - to do it we need set ADC_CR2_ADON again!
|
||||||
|
ADC1_CR2 |= ADC_CR2_ADON;
|
||||||
|
}
|
||||||
|
|
||||||
|
adwd_stat adc_status[ADC_CHANNEL_NUMBER] = {ADWD_MID, ADWD_MID};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watchdog works on both channels, so we need to save status of WD events
|
||||||
|
* to prevent repeated events on constant signal level
|
||||||
|
*
|
||||||
|
void adc1_2_isr(){
|
||||||
|
int i;
|
||||||
|
if(ADC1_SR & ADC_SR_AWD){ // analog watchdog event
|
||||||
|
for(i = 0; i < ADC_CHANNEL_NUMBER; ++i){
|
||||||
|
uint16_t val = ADC_value[i];
|
||||||
|
adwd_stat st = adc_status[i];
|
||||||
|
// if(adc_ms[i] == DIDNT_TRIGGERED){
|
||||||
|
if(val > ADC_WDG_HIGH){ // watchdog event on high level
|
||||||
|
if(st != ADWD_HI){
|
||||||
|
adc_ms[i] = Timer;
|
||||||
|
memcpy(&adc_time, ¤t_time, sizeof(curtime));
|
||||||
|
adc_status[i] = ADWD_HI;
|
||||||
|
ADC_trig_val[i] = val;
|
||||||
|
}
|
||||||
|
}else if(val < ADC_WDG_LOW){ // watchdog event on low level
|
||||||
|
if(st != ADWD_LOW){
|
||||||
|
adc_ms[i] = Timer;
|
||||||
|
memcpy(&adc_time, ¤t_time, sizeof(curtime));
|
||||||
|
adc_status[i] = ADWD_LOW;
|
||||||
|
ADC_trig_val[i] = val;
|
||||||
|
}
|
||||||
|
}else if(val > ADC_WDG_LOW+ADC_WDG_THRES && val < ADC_WDG_HIGH-ADC_WDG_THRES){
|
||||||
|
adc_status[i] = ADWD_MID;
|
||||||
|
if(adc_ms[i] == Timer) // remove noice
|
||||||
|
adc_ms[i] = DIDNT_TRIGGERED;
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ADC1_SR = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// levels for thresholding
|
||||||
|
const uint16_t ADC_lowlevel[2] = {900, 2700}; // signal if ADC value < lowlevel
|
||||||
|
const uint16_t ADC_highlevel[2] = {2200, 5000}; // signal if ADC value > highlevel
|
||||||
|
const uint16_t ADC_midlevel[2] = {1400, 3000}; // when transit through midlevel set status as ADWD_MID
|
||||||
|
|
||||||
|
void poll_ADC(){
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < ADC_CHANNEL_NUMBER; ++i){
|
||||||
|
uint16_t val = ADC_value[i];
|
||||||
|
adwd_stat st = adc_status[i];
|
||||||
|
if(val > ADC_highlevel[i]){ // watchdog event on high level
|
||||||
|
if(st != ADWD_HI){
|
||||||
|
adc_ms[i] = Timer;
|
||||||
|
memcpy(&adc_time[i], ¤t_time, sizeof(curtime));
|
||||||
|
adc_status[i] = ADWD_HI;
|
||||||
|
ADC_trig_val[i] = val;
|
||||||
|
}
|
||||||
|
}else if(val < ADC_lowlevel[i]){ // watchdog event on low level
|
||||||
|
if(st != ADWD_LOW){
|
||||||
|
adc_ms[i] = Timer;
|
||||||
|
memcpy(&adc_time[i], ¤t_time, sizeof(curtime));
|
||||||
|
adc_status[i] = ADWD_LOW;
|
||||||
|
ADC_trig_val[i] = val;
|
||||||
|
}
|
||||||
|
}else if((st == ADWD_HI && val < ADC_midlevel[i]) ||
|
||||||
|
(st == ADWD_LOW && val > ADC_midlevel[i])){
|
||||||
|
adc_status[i] = ADWD_MID;
|
||||||
|
if(adc_ms[i] == Timer) // remove noice
|
||||||
|
adc_ms[i] = DIDNT_TRIGGERED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
F1/GPS+ultrasonic/adc.h
Normal file
52
F1/GPS+ultrasonic/adc.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* adc.h
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __SHARP_H__
|
||||||
|
#define __SHARP_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern uint16_t ADC_value[];
|
||||||
|
extern uint16_t ADC_trig_val[];
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
ADWD_LOW, // watchdog at low-level
|
||||||
|
ADWD_MID, // normal state
|
||||||
|
ADWD_HI // watchdog at high-level
|
||||||
|
} adwd_stat;
|
||||||
|
|
||||||
|
extern adwd_stat adc_status[];
|
||||||
|
|
||||||
|
|
||||||
|
#define ADC_CHANNEL_NUMBER (2)
|
||||||
|
|
||||||
|
// something near
|
||||||
|
#define ADC_WDG_HIGH ((uint16_t)1500)
|
||||||
|
// nothing in front of sensor
|
||||||
|
#define ADC_WDG_LOW ((uint16_t)700)
|
||||||
|
// threshold above levels
|
||||||
|
#define ADC_WDG_THRES ((uint16_t)200)
|
||||||
|
|
||||||
|
void init_adc_sensor();
|
||||||
|
void poll_ADC();
|
||||||
|
|
||||||
|
#endif // __SHARP_H__
|
||||||
314
F1/GPS+ultrasonic/cdcacm.c
Normal file
314
F1/GPS+ultrasonic/cdcacm.c
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cdcacm.h"
|
||||||
|
#include "user_proto.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
// Buffer for USB Tx
|
||||||
|
static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE];
|
||||||
|
static uint8_t USB_Tx_ptr = 0;
|
||||||
|
// connection flag
|
||||||
|
uint8_t USB_connected = 0;
|
||||||
|
static const struct usb_device_descriptor dev = {
|
||||||
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
.bDeviceClass = USB_CLASS_CDC,
|
||||||
|
.bDeviceSubClass = 0,
|
||||||
|
.bDeviceProtocol = 0,
|
||||||
|
.bMaxPacketSize0 = 64,
|
||||||
|
.idVendor = 0x0483,
|
||||||
|
.idProduct = 0x5740,
|
||||||
|
.bcdDevice = 0x0200,
|
||||||
|
.iManufacturer = 1,
|
||||||
|
.iProduct = 2,
|
||||||
|
.iSerialNumber = 3,
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
char usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data
|
||||||
|
int usbdatalen = 0; // lenght of received data
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This notification endpoint isn't implemented. According to CDC spec its
|
||||||
|
* optional, but its absence causes a NULL pointer dereference in Linux
|
||||||
|
* cdc_acm driver.
|
||||||
|
*/
|
||||||
|
static const struct usb_endpoint_descriptor comm_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x83,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
|
.wMaxPacketSize = 16,
|
||||||
|
.bInterval = 255,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_endpoint_descriptor data_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x01,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}, {
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x82,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 64,
|
||||||
|
.bInterval = 1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
struct usb_cdc_header_descriptor header;
|
||||||
|
struct usb_cdc_call_management_descriptor call_mgmt;
|
||||||
|
struct usb_cdc_acm_descriptor acm;
|
||||||
|
struct usb_cdc_union_descriptor cdc_union;
|
||||||
|
} __attribute__((packed)) cdcacm_functional_descriptors = {
|
||||||
|
.header = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
|
||||||
|
.bcdCDC = 0x0110,
|
||||||
|
},
|
||||||
|
.call_mgmt = {
|
||||||
|
.bFunctionLength =
|
||||||
|
sizeof(struct usb_cdc_call_management_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
.bDataInterface = 1,
|
||||||
|
},
|
||||||
|
.acm = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
},
|
||||||
|
.cdc_union = {
|
||||||
|
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||||
|
.bDescriptorType = CS_INTERFACE,
|
||||||
|
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||||
|
.bControlInterface = 0,
|
||||||
|
.bSubordinateInterface0 = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor comm_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 0,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = comm_endp,
|
||||||
|
|
||||||
|
.extra = &cdcacm_functional_descriptors,
|
||||||
|
.extralen = sizeof(cdcacm_functional_descriptors),
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface_descriptor data_iface[] = {{
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 2,
|
||||||
|
.bInterfaceClass = USB_CLASS_DATA,
|
||||||
|
.bInterfaceSubClass = 0,
|
||||||
|
.bInterfaceProtocol = 0,
|
||||||
|
.iInterface = 0,
|
||||||
|
|
||||||
|
.endpoint = data_endp,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_interface ifaces[] = {{
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = comm_iface,
|
||||||
|
}, {
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.altsetting = data_iface,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const struct usb_config_descriptor config = {
|
||||||
|
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||||
|
.wTotalLength = 0,
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = 1,
|
||||||
|
.iConfiguration = 0,
|
||||||
|
.bmAttributes = 0x80,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
|
||||||
|
.interface = ifaces,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *usb_strings[] = {
|
||||||
|
"Organisation, author",
|
||||||
|
"device",
|
||||||
|
"version",
|
||||||
|
};
|
||||||
|
|
||||||
|
// default line coding: B115200, 1stop, 8bits, parity none
|
||||||
|
struct usb_cdc_line_coding linecoding = {
|
||||||
|
.dwDTERate = 115200,
|
||||||
|
.bCharFormat = USB_CDC_1_STOP_BITS,
|
||||||
|
.bParityType = USB_CDC_NO_PARITY,
|
||||||
|
.bDataBits = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Buffer to be used for control requests. */
|
||||||
|
uint8_t usbd_control_buffer[128];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function runs every time it gets a request for control parameters get/set
|
||||||
|
* parameter SET_LINE_CODING used to change USART1 parameters: if you want to
|
||||||
|
* change them, just connect through USB with required parameters
|
||||||
|
*/
|
||||||
|
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
|
||||||
|
uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){
|
||||||
|
(void)complete;
|
||||||
|
(void)buf;
|
||||||
|
(void)usbd_dev;
|
||||||
|
char local_buf[10];
|
||||||
|
struct usb_cdc_line_coding lc;
|
||||||
|
|
||||||
|
switch (req->bRequest) {
|
||||||
|
case SET_CONTROL_LINE_STATE:{
|
||||||
|
if(req->wValue){ // terminal is opened
|
||||||
|
USB_connected = 1;
|
||||||
|
}else{ // terminal is closed
|
||||||
|
USB_connected = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This Linux cdc_acm driver requires this to be implemented
|
||||||
|
* even though it's optional in the CDC spec, and we don't
|
||||||
|
* advertise it in the ACM functional descriptor.
|
||||||
|
*/
|
||||||
|
struct usb_cdc_notification *notif = (void *)local_buf;
|
||||||
|
/* We echo signals back to host as notification. */
|
||||||
|
notif->bmRequestType = 0xA1;
|
||||||
|
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
|
||||||
|
notif->wValue = 0;
|
||||||
|
notif->wIndex = 0;
|
||||||
|
notif->wLength = 2;
|
||||||
|
local_buf[8] = req->wValue & 3;
|
||||||
|
local_buf[9] = 0;
|
||||||
|
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
|
||||||
|
}break;
|
||||||
|
case SET_LINE_CODING:
|
||||||
|
if (!len || (*len != sizeof(struct usb_cdc_line_coding)))
|
||||||
|
return 0;
|
||||||
|
memcpy((void *)&lc, (void *)*buf, *len);
|
||||||
|
// Mark & Space parity don't support by hardware, check it
|
||||||
|
if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){
|
||||||
|
return 0; // error
|
||||||
|
}else{
|
||||||
|
// memcpy((void *)&linecoding, (void *)&lc, sizeof(struct usb_cdc_line_coding));
|
||||||
|
// UART_setspeed(USART1, &linecoding);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GET_LINE_CODING: // return linecoding buffer
|
||||||
|
if(len && *len == sizeof(struct usb_cdc_line_coding))
|
||||||
|
memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding));
|
||||||
|
//usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen);
|
||||||
|
usbdatalen += len;
|
||||||
|
if(usbdatalen >= USB_RX_DATA_SIZE){ // buffer overflow - drop all its contents
|
||||||
|
usbdatalen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){
|
||||||
|
(void)ep;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
|
||||||
|
{
|
||||||
|
(void)wValue;
|
||||||
|
(void)usbd_dev;
|
||||||
|
|
||||||
|
usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb);
|
||||||
|
usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
|
|
||||||
|
usbd_register_control_callback(
|
||||||
|
usbd_dev,
|
||||||
|
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||||
|
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||||
|
cdcacm_control_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbd_device *current_usb = NULL;
|
||||||
|
|
||||||
|
usbd_device *USB_init(){
|
||||||
|
current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config,
|
||||||
|
usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
if(!current_usb) return NULL;
|
||||||
|
usbd_register_set_config_callback(current_usb, cdcacm_set_config);
|
||||||
|
return current_usb;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_t send_block_mutex = MUTEX_UNLOCKED;
|
||||||
|
/**
|
||||||
|
* Put byte into USB buffer to send
|
||||||
|
* @param byte - a byte to put into a buffer
|
||||||
|
*/
|
||||||
|
void usb_send(uint8_t byte){
|
||||||
|
mutex_lock(&send_block_mutex);
|
||||||
|
USB_Tx_Buffer[USB_Tx_ptr++] = byte;
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it!
|
||||||
|
usb_send_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send all data in buffer over USB
|
||||||
|
* this function runs when buffer is full or on SysTick
|
||||||
|
*/
|
||||||
|
void usb_send_buffer(){
|
||||||
|
if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return;
|
||||||
|
if(USB_Tx_ptr){
|
||||||
|
if(current_usb && USB_connected){
|
||||||
|
// usbd_ep_write_packet return 0 if previous packet isn't transmit yet
|
||||||
|
while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr));
|
||||||
|
usbd_poll(current_usb);
|
||||||
|
}
|
||||||
|
USB_Tx_ptr = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&send_block_mutex);
|
||||||
|
}
|
||||||
54
F1/GPS+ultrasonic/cdcacm.h
Normal file
54
F1/GPS+ultrasonic/cdcacm.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ccdcacm.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __CCDCACM_H__
|
||||||
|
#define __CCDCACM_H__
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
|
// commands through EP0
|
||||||
|
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define GET_ENCAPSULATED_RESPONSE 0x01
|
||||||
|
#define SET_COMM_FEATURE 0x02
|
||||||
|
#define GET_COMM_FEATURE 0x03
|
||||||
|
#define CLEAR_COMM_FEATURE 0x04
|
||||||
|
#define SET_LINE_CODING 0x20
|
||||||
|
#define GET_LINE_CODING 0x21
|
||||||
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define SEND_BREAK 0x23
|
||||||
|
|
||||||
|
// Size of input/output buffers
|
||||||
|
#define USB_TX_DATA_SIZE 64
|
||||||
|
#define USB_RX_DATA_SIZE 64
|
||||||
|
|
||||||
|
// USB connection flag
|
||||||
|
extern uint8_t USB_connected;
|
||||||
|
extern struct usb_cdc_line_coding linecoding;
|
||||||
|
|
||||||
|
extern char usbdatabuf[];
|
||||||
|
extern int usbdatalen;
|
||||||
|
|
||||||
|
usbd_device *USB_init();
|
||||||
|
void usb_send(uint8_t byte);
|
||||||
|
void usb_send_buffer();
|
||||||
|
|
||||||
|
#endif // __CCDCACM_H__
|
||||||
121
F1/GPS+ultrasonic/hardware_ini.c
Normal file
121
F1/GPS+ultrasonic/hardware_ini.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.c - functions for HW initialisation
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All hardware-dependent initialisation & definition should be placed here
|
||||||
|
* and in hardware_ini.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "hardware_ini.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPIO initialisaion: clocking + pins setup
|
||||||
|
*/
|
||||||
|
void GPIO_init(){
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
|
||||||
|
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN |
|
||||||
|
RCC_APB2ENR_IOPEEN);
|
||||||
|
/*
|
||||||
|
* Setup EXTI on PA4 (PPS input from GPS) - pull down
|
||||||
|
* EXTI on PA5 - also pull down (trigger for time measurement)
|
||||||
|
*/
|
||||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO4 | GPIO5);
|
||||||
|
//AFIO_EXTICR2 = 0;
|
||||||
|
exti_enable_request(EXTI4 | EXTI5);
|
||||||
|
// trigger on rising edge
|
||||||
|
exti_set_trigger(EXTI4 | EXTI5, EXTI_TRIGGER_RISING);
|
||||||
|
nvic_enable_irq(NVIC_EXTI4_IRQ);
|
||||||
|
nvic_enable_irq(NVIC_EXTI9_5_IRQ);
|
||||||
|
/*
|
||||||
|
// Buttons: pull-up input
|
||||||
|
gpio_set_mode(BTNS_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
|
||||||
|
BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// turn on pull-up
|
||||||
|
gpio_set(BTNS_PORT, BTN_S2_PIN | BTN_S3_PIN);
|
||||||
|
// LEDS: opendrain output
|
||||||
|
gpio_set_mode(LEDS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
|
||||||
|
LED_D1_PIN | LED_D2_PIN);
|
||||||
|
// turn off LEDs
|
||||||
|
gpio_set(LEDS_PORT, LED_D1_PIN | LED_D2_PIN);*/
|
||||||
|
/*
|
||||||
|
// USB_DISC: push-pull
|
||||||
|
gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ,
|
||||||
|
GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN);
|
||||||
|
// USB_POWER: open drain, externall pull down with R7 (22k)
|
||||||
|
gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT,
|
||||||
|
GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SysTick used for system timer with period of 1ms
|
||||||
|
*/
|
||||||
|
void SysTick_init(){
|
||||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
||||||
|
STK_RVR = STK_RVR_DEFAULT_VAL; // 9000 pulses: 1kHz
|
||||||
|
systick_interrupt_enable();
|
||||||
|
systick_counter_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PA5 interrupt - print time at button/switch trigger
|
||||||
|
*/
|
||||||
|
void exti9_5_isr(){
|
||||||
|
if(EXTI_PR & EXTI5){
|
||||||
|
if(trigger_ms == DIDNT_TRIGGERED){ // prevent bounce
|
||||||
|
trigger_ms = Timer;
|
||||||
|
memcpy(&trigger_time, ¤t_time, sizeof(curtime));
|
||||||
|
}
|
||||||
|
EXTI_PR = EXTI5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// check buttons S2/S3
|
||||||
|
void check_btns(){
|
||||||
|
static uint8_t oldstate[2] = {1,1}; // old buttons state
|
||||||
|
uint8_t newstate[2], i;
|
||||||
|
static uint32_t Old_timer[2] = {0,0};
|
||||||
|
newstate[0] = gpio_get(BTNS_PORT, BTN_S2_PIN) ? 1 : 0;
|
||||||
|
newstate[1] = gpio_get(BTNS_PORT, BTN_S3_PIN) ? 1 : 0;
|
||||||
|
for(i = 0; i < 2; i++){
|
||||||
|
uint8_t new = newstate[i];
|
||||||
|
// pause for 60ms
|
||||||
|
uint32_t O = Old_timer[i];
|
||||||
|
if(O){
|
||||||
|
if(Timer - O > 60 || O > Timer){
|
||||||
|
P("Button S");
|
||||||
|
usb_send('2' + i);
|
||||||
|
if(new) P("released");
|
||||||
|
else P("pressed");
|
||||||
|
newline();
|
||||||
|
oldstate[i] = new;
|
||||||
|
Old_timer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(new != oldstate[i]){
|
||||||
|
Old_timer[i] = Timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
76
F1/GPS+ultrasonic/hardware_ini.h
Normal file
76
F1/GPS+ultrasonic/hardware_ini.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* hardware_ini.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __HARDWARE_INI_H__
|
||||||
|
#define __HARDWARE_INI_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timers:
|
||||||
|
* SysTick - system time
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void GPIO_init();
|
||||||
|
void SysTick_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons on devboard
|
||||||
|
*/
|
||||||
|
#define BTNS_PORT GPIOC
|
||||||
|
// PCO -- S2
|
||||||
|
#define BTN_S2_PIN GPIO0
|
||||||
|
// PC1 -- S3
|
||||||
|
#define BTN_S3_PIN GPIO1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LEDS: PB9 for D1, PB8 for D2
|
||||||
|
*/
|
||||||
|
#define LEDS_PORT GPIOB
|
||||||
|
#define LED_D1_PIN GPIO9
|
||||||
|
#define LED_D2_PIN GPIO8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB interface
|
||||||
|
* connect boot1 jumper to gnd, boot0 to gnd; and reconnect boot0 to +3.3 to boot flash
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
// USB_DICS (disconnect) - PC11
|
||||||
|
#define USB_DISC_PIN GPIO11
|
||||||
|
#define USB_DISC_PORT GPIOC
|
||||||
|
// USB_POWER (high level when USB connected to PC)
|
||||||
|
#define USB_POWER_PIN GPIO10
|
||||||
|
#define USB_POWER_PORT GPIOC
|
||||||
|
// change signal level on USB diconnect pin
|
||||||
|
#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN)
|
||||||
|
// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level
|
||||||
|
// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level
|
||||||
|
#define usb_disconnect() usb_disc_high()
|
||||||
|
#define usb_connect() usb_disc_low()
|
||||||
|
*/
|
||||||
|
// my simple devboard have no variants for programmed connection/disconnection of USB
|
||||||
|
#define usb_disconnect()
|
||||||
|
#define usb_connect()
|
||||||
|
|
||||||
|
void check_btns();
|
||||||
|
|
||||||
|
#endif // __HARDWARE_INI_H__
|
||||||
9
F1/GPS+ultrasonic/ld/devices.data
Normal file
9
F1/GPS+ultrasonic/ld/devices.data
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
stm32f103?4* stm32f1 ROM=16K RAM=6K
|
||||||
|
stm32f103?6* stm32f1 ROM=32K RAM=10K
|
||||||
|
stm32f103?8* stm32f1 ROM=64K RAM=20K
|
||||||
|
stm32f103?b* stm32f1 ROM=128K RAM=20K
|
||||||
|
stm32f103?c* stm32f1 ROM=256K RAM=48K
|
||||||
|
stm32f103?d* stm32f1 ROM=384K RAM=64K
|
||||||
|
stm32f103?e* stm32f1 ROM=512K RAM=64K
|
||||||
|
stm32f103?f* stm32f1 ROM=768K RAM=96K
|
||||||
|
stm32f103?g* stm32f1 ROM=1024K RAM=96K
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103x4.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103x4.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103x6.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103x6.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103x8.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103x8.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103xB.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103xB.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103xC.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103xC.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103xD.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103xD.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103xE.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103xE.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
31
F1/GPS+ultrasonic/ld/stm32f103xF.ld
Normal file
31
F1/GPS+ultrasonic/ld/stm32f103xF.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopencm3 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Linker script for STM32F100x4, 16K flash, 4K RAM. */
|
||||||
|
|
||||||
|
/* Define memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include the common ld script. */
|
||||||
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user