Reorganize repository to be used as a library
Project was organized as an application, wich makes it less practical to include in other projects. A template project may be added back to make up for the missing files
This commit is contained in:
parent
a2c41b51b4
commit
4a12fa7a3d
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 Steins7
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
189
Makefile
189
Makefile
@ -1,189 +0,0 @@
|
|||||||
#-------------------------------------------------------------------------------
|
|
||||||
# this GNU-makefile relies on the GCC toolchain
|
|
||||||
|
|
||||||
# --- control global project settings
|
|
||||||
# RELEASE=1 -> enable optimisation, then disable debug
|
|
||||||
# RELEASE=0 -> disable optimisation, then enable debug
|
|
||||||
RELEASE=0
|
|
||||||
|
|
||||||
# --- project architecture
|
|
||||||
# program name
|
|
||||||
EXE_PREFIX=main
|
|
||||||
# project folders, This Makefile should be in the same folder as the SRC folder
|
|
||||||
SRC=src
|
|
||||||
BIN=bin
|
|
||||||
INC=include
|
|
||||||
LIB=lib
|
|
||||||
OBJ=${BIN}/obj
|
|
||||||
DEP=${BIN}/dep
|
|
||||||
# code folders, in the SRC folder
|
|
||||||
SUBFOLDERS=drivers target
|
|
||||||
# Define linker script file here
|
|
||||||
LDSCRIPT=${SRC}/target/STM32F103XB.ld
|
|
||||||
|
|
||||||
# --- advanced config
|
|
||||||
# List all user C define here
|
|
||||||
UDEFS=
|
|
||||||
# Define ASM defines here
|
|
||||||
UADEFS=
|
|
||||||
|
|
||||||
# --- toolchain configuration
|
|
||||||
TARGET=arm-none-eabi-
|
|
||||||
CC=${TARGET}gcc
|
|
||||||
CPP=${TARGET}g++
|
|
||||||
OBJCOPY=${TARGET}objcopy
|
|
||||||
AS=${TARGET}gcc -x assembler-with-cpp -c
|
|
||||||
SIZE=${TARGET}size
|
|
||||||
OBJDUMP=${TARGET}objdump
|
|
||||||
|
|
||||||
# --- hardware settings
|
|
||||||
ARCH=armv7-m
|
|
||||||
FLOAT-ABI=soft #no FPU on stm32f103
|
|
||||||
CPU=cortex-m3
|
|
||||||
CPUFLAGS=-mthumb
|
|
||||||
FPU=fpv4-sp-d16 #"FLOAT-ABI=soft" disable that
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# --- makefile pre-incantation
|
|
||||||
|
|
||||||
# List all de:fault C defines here, like -D_DEBUG=1
|
|
||||||
DDEFS=-march=${ARCH} -mfloat-abi=${FLOAT-ABI} -mcpu=${CPU} -mfpu=${FPU} $\
|
|
||||||
${CPUFLAGS}
|
|
||||||
# List all default ASM defines here, like -D_DEBUG=1
|
|
||||||
DADEFS=-D__ASSEMBLY__
|
|
||||||
|
|
||||||
# --- deduce file names
|
|
||||||
MAIN_C_FILES=${wildcard ${SRC}/${strip ${EXE_PREFIX}}*.c}
|
|
||||||
MAIN_CPP_FILES=${wildcard ${SRC}/${strip ${EXE_PREFIX}}*.cpp}
|
|
||||||
|
|
||||||
COMMON_C_FILES=${filter-out ${MAIN_C_FILES},${wildcard ${SRC}/*.c}}
|
|
||||||
COMMON_C_FILES+=${foreach dir,${SUBFOLDERS},${wildcard ${SRC}/${dir}/*.c}}
|
|
||||||
|
|
||||||
COMMON_CPP_FILES=${filter-out ${MAIN_CPP_FILES},${wildcard ${SRC}/*.cpp}}
|
|
||||||
COMMON_CPP_FILES+=${foreach dir,${SUBFOLDERS},${wildcard ${SRC}/${dir}/*.cpp}}
|
|
||||||
|
|
||||||
COMMON_ASM_FILES=${foreach dir,${SUBFOLDERS},${wildcard ${SRC}/${dir}/*.s}}
|
|
||||||
|
|
||||||
MAIN_OBJECT_FILES=${sort ${patsubst ${src}/%.c,${obj}/%.o,${MAIN_C_FILES}} \
|
|
||||||
${patsubst ${src}/%.cpp,${obj}/%.o,${MAIN_CPP_FILES}}}
|
|
||||||
COMMON_OBJECT_FILES=${sort \
|
|
||||||
${patsubst ${SRC}/%.c,${OBJ}/%.o,${COMMON_C_FILES}} \
|
|
||||||
${patsubst ${SRC}/%.cpp,${OBJ}/%.o,${COMMON_CPP_FILES}} \
|
|
||||||
${patsubst ${SRC}/%s,${OBJ}/%o,${COMMON_ASM_FILES}}}
|
|
||||||
|
|
||||||
LIBRARIES=${foreach dir,${wildcard ${LIB}/*},${wildcard ${LIB}/${dir}/*.a}}
|
|
||||||
|
|
||||||
OBJECT_FILES=${MAIN_OBJECT_FILES} ${COMMON_OBJECT_FILES}
|
|
||||||
DEPEND_FILES=${OBJECT_FILES:%.o,%.d}
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# --- makefile incantation
|
|
||||||
# down here is black magic, you probably don't want to modify anything
|
|
||||||
|
|
||||||
DEFS=${DDEFS} ${UDEFS}
|
|
||||||
ADEFS=${DADEFS} ${UADEFS}
|
|
||||||
|
|
||||||
# --- otpimisation
|
|
||||||
ifeq (${strip ${RELEASE}},0)
|
|
||||||
CFLAGS=-g3 -O0
|
|
||||||
else
|
|
||||||
CFLAGS=-O3
|
|
||||||
endif
|
|
||||||
|
|
||||||
# --- c/cpp
|
|
||||||
ifneq (${strip ${MAIN_CPP_FILES} ${COMMON_CPP_FILES}},)
|
|
||||||
CC:=${CPP}
|
|
||||||
CFLAGS+=-std=c++17
|
|
||||||
else
|
|
||||||
CFLAGS+=-std=c17
|
|
||||||
endif
|
|
||||||
|
|
||||||
ASFLAGS=${LIB} $(DEFS) -Wa,--gdwarf2 $(ADEFS)
|
|
||||||
CFLAGS+=-Wall ${DEFS} -Wextra -Warray-bounds -Wno-unused-parameter $\
|
|
||||||
-fomit-frame-pointer
|
|
||||||
LDFLAGS=-T ${LDSCRIPT} -lc -lgcc -lgcov -lm -Wl,-Map=$@.map,--gc-sections $\
|
|
||||||
--specs=nosys.specs
|
|
||||||
INCLUDE=-I ${INC}
|
|
||||||
|
|
||||||
# --- Generate dependency information
|
|
||||||
CFLAGS+=-MD -MP -MF ${patsubst %o,%d,$@}
|
|
||||||
ASFLAGS+=#-MD -MP -MF ${patsubst %o,%d,$@}
|
|
||||||
|
|
||||||
# --- folder tree
|
|
||||||
DIR_GUARD=@mkdir -p ${@D}
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# --- make rules
|
|
||||||
all: ${BIN}/${EXE_PREFIX}.elf ${BIN}/${EXE_PREFIX}.hex ${BIN}/${EXE_PREFIX}.bin
|
|
||||||
|
|
||||||
rebuild : clean all
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
.SECONDARY:
|
|
||||||
.PHONY: all clean rebuild
|
|
||||||
|
|
||||||
# --- compiler command for elf file
|
|
||||||
${BIN}/%.elf : ${MAIN_OBJECT_FILES} ${COMMON_OBJECT_FILES}
|
|
||||||
@echo -e '\e[32;1m ==== linking $@ ====\e[0m'
|
|
||||||
@echo ${COMMON_OBJECT_FILES}
|
|
||||||
@echo
|
|
||||||
${DIR_GUARD}
|
|
||||||
${CC} ${INCLUDE} ${CFLAGS} -o $@ $^ ${LIBRARIES} ${LDFLAGS}
|
|
||||||
${OBJDUMP} -h $@
|
|
||||||
${SIZE} $@
|
|
||||||
@echo
|
|
||||||
|
|
||||||
# --- compiler commands for uploadable files
|
|
||||||
${BIN}/%.hex : ${BIN}/%.elf
|
|
||||||
@echo -e '\e[33;1m ==== translating $< ====\e[0m'
|
|
||||||
${OBJCOPY} -O ihex $< $@
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${BIN}/%.bin : ${BIN}/%.elf
|
|
||||||
@echo -e '\e[33;1m ==== translating $< ====\e[0m'
|
|
||||||
${OBJCOPY} -O binary $< $@
|
|
||||||
@echo
|
|
||||||
|
|
||||||
# --- compiler commands for every source file
|
|
||||||
${OBJ}/%.o : ${SRC}/%.cpp
|
|
||||||
@echo -e '\e[36;1m ==== compiling $< ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${CPP} ${INCLUDE} -c ${CFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${BIN}/%.o : ${SRC}/%.cpp
|
|
||||||
@echo -e '\e[36;1m ==== compiling $< ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${CPP} ${INCLUDE} -c ${CFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${OBJ}/%.o : ${SRC}/%.c
|
|
||||||
@echo -e '\e[34;1m ==== compiling $< ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${CC} ${INCLUDE} -c ${CFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${BIN}/%.o : ${SRC}/%.c
|
|
||||||
@echo -e '\e[34;1m ==== compiling $< ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${CC} ${INCLUDE} -c ${CFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${OBJ}/%.o : ${SRC}/%.s
|
|
||||||
@echo -e '\e[35;1m ==== compiling $^ ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${AS} -o ${ASFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
${BIN}/%.o : ${SRC}/%.s
|
|
||||||
@echo -e '\e[35;1m ==== compiling $^ ====\e[0m'
|
|
||||||
${DIR_GUARD}
|
|
||||||
${AS} -o ${ASFLAGS} $< -o $@ ${LIBRARIES}
|
|
||||||
@echo
|
|
||||||
|
|
||||||
# --- remove generated files
|
|
||||||
clean:
|
|
||||||
-rm -rf ${BIN}/*
|
|
||||||
|
|
||||||
-include ${DEPEND_FILES}
|
|
||||||
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
# stm32f1xx_HBL
|
|
||||||
simplified HAL for stm32f1 microcontrollers, designed to be easily customized
|
|
||||||
3
openocd
3
openocd
@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
openocd -f interface/stlink.cfg -f target/cs32f1x.cfg
|
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint16_t pin_cfg, OnIO cb) {
|
|||||||
gpio->BSRR |= odr;
|
gpio->BSRR |= odr;
|
||||||
|
|
||||||
//TODO manage alternate functions
|
//TODO manage alternate functions
|
||||||
|
|
||||||
// manage IRQs //TODO allow IRQ reset
|
// manage IRQs //TODO allow IRQ reset
|
||||||
if (!cb) return 0; //no callback attached
|
if (!cb) return 0; //no callback attached
|
||||||
|
|
||||||
@ -198,26 +198,26 @@ int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint16_t pin_cfg, OnIO cb) {
|
|||||||
|
|
||||||
|
|
||||||
uint32_t io_read(GPIO_TypeDef *gpio, uint16_t mask)
|
uint32_t io_read(GPIO_TypeDef *gpio, uint16_t mask)
|
||||||
{
|
{
|
||||||
return gpio->IDR & mask;
|
return gpio->IDR & mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_write(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
|
void io_write(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
|
||||||
{
|
{
|
||||||
gpio->BSRR = (uint32_t)(mask) << (val ? 0 : 16);
|
gpio->BSRR = (uint32_t)(mask) << (val ? 0 : 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_write_n(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
|
void io_write_n(GPIO_TypeDef *gpio, uint16_t val, uint16_t mask)
|
||||||
{
|
{
|
||||||
gpio->BSRR = (uint32_t)(mask) << (val ? 16 : 0);
|
gpio->BSRR = (uint32_t)(mask) << (val ? 16 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_set(GPIO_TypeDef *gpio, uint16_t mask)
|
void io_set(GPIO_TypeDef *gpio, uint16_t mask)
|
||||||
{
|
{
|
||||||
gpio->BSRR = mask;
|
gpio->BSRR = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_clear(GPIO_TypeDef *gpio, uint16_t mask)
|
void io_clear(GPIO_TypeDef *gpio, uint16_t mask)
|
||||||
{
|
{
|
||||||
gpio->BSRR = (uint32_t)(mask) << 16;
|
gpio->BSRR = (uint32_t)(mask) << 16;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/drivers/rnd.c
Normal file
20
src/drivers/rnd.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "rnd.h"
|
||||||
|
|
||||||
|
uint32_t rnd_seed = 251;
|
||||||
|
|
||||||
|
void set_rnd_seed(uint32_t seed) {
|
||||||
|
rnd_seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rnd_byte() {
|
||||||
|
|
||||||
|
static uint32_t r = 251;
|
||||||
|
static uint32_t Y = 7;
|
||||||
|
|
||||||
|
if (r==0 || r==1 || r==0xFFFFFFFF) r=251;
|
||||||
|
r = (9973 * ~r) + ((Y) % 701);
|
||||||
|
Y = (r>>24) % 255;
|
||||||
|
|
||||||
|
return (uint8_t)Y;
|
||||||
|
}
|
||||||
|
|
||||||
11
src/drivers/rnd.h
Normal file
11
src/drivers/rnd.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef RND_H
|
||||||
|
#define RND_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
void set_rnd_seed(uint32_t seed);
|
||||||
|
|
||||||
|
uint8_t rnd_byte();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -33,52 +33,62 @@ int timer_config_cb(TIM_TypeDef* tmr, uint32_t* clk, OnTick cb) {
|
|||||||
IRQn_Type irqn;
|
IRQn_Type irqn;
|
||||||
uint32_t irq_priority;
|
uint32_t irq_priority;
|
||||||
|
|
||||||
// get clocks config
|
switch((uint32_t)tmr) {
|
||||||
if (tmr == TIM1) {
|
case (uint32_t)TIM1:
|
||||||
*clk = sysclks.apb2_timer_freq;
|
// get clocks config
|
||||||
|
*clk = sysclks.apb2_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback1 = cb;
|
callback1 = cb;
|
||||||
irqn = TIM1_UP_IRQn; //every update
|
irqn = TIM1_UP_IRQn; //every update
|
||||||
irq_priority = TIM1_IRQ_PRIORITY;
|
irq_priority = TIM1_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB2ENR |= 1<<11;
|
RCC->APB2ENR |= 1<<11;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM2) {
|
case (uint32_t)TIM2:
|
||||||
*clk = sysclks.apb1_timer_freq;
|
// get clocks config
|
||||||
|
*clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback2 = cb;
|
callback2 = cb;
|
||||||
irqn = TIM2_IRQn;
|
irqn = TIM2_IRQn;
|
||||||
irq_priority = TIM2_IRQ_PRIORITY;
|
irq_priority = TIM2_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |= 1<<0;
|
RCC->APB1ENR |= 1<<0;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM3) {
|
case (uint32_t)TIM3:
|
||||||
*clk = sysclks.apb1_timer_freq;
|
// get clocks config
|
||||||
|
*clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback3 = cb;
|
callback3 = cb;
|
||||||
irqn = TIM3_IRQn;
|
irqn = TIM3_IRQn;
|
||||||
irq_priority = TIM3_IRQ_PRIORITY;
|
irq_priority = TIM3_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |= 1<<1;
|
RCC->APB1ENR |= 1<<1;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM4) {
|
case (uint32_t)TIM4:
|
||||||
*clk = sysclks.apb1_timer_freq;
|
// get clocks config
|
||||||
|
*clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback4 = cb;
|
callback4 = cb;
|
||||||
irqn = TIM4_IRQn;
|
irqn = TIM4_IRQn;
|
||||||
irq_priority = TIM4_IRQ_PRIORITY;
|
irq_priority = TIM4_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB1ENR |= 1<<2;
|
RCC->APB1ENR |= 1<<2;
|
||||||
|
break;
|
||||||
} else return -1;
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// clear pending interrupts
|
// clear pending interrupts
|
||||||
tmr->SR &= !1;
|
tmr->SR &= !1;
|
||||||
@ -184,52 +194,62 @@ int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb) {
|
|||||||
IRQn_Type irqn;
|
IRQn_Type irqn;
|
||||||
uint32_t irq_priority, clk;
|
uint32_t irq_priority, clk;
|
||||||
|
|
||||||
// get back the clock frequency
|
switch((uint32_t)tmr) {
|
||||||
if (tmr == TIM1) {
|
case (uint32_t)TIM1:
|
||||||
clk = sysclks.apb2_timer_freq;
|
// get back the clock frequency
|
||||||
|
clk = sysclks.apb2_timer_freq;
|
||||||
|
|
||||||
// register callback function
|
// register callback function
|
||||||
callback1 = cb;
|
callback1 = cb;
|
||||||
irqn = TIM1_UP_IRQn; //every update
|
irqn = TIM1_UP_IRQn; //every update
|
||||||
irq_priority = TIM1_IRQ_PRIORITY;
|
irq_priority = TIM1_IRQ_PRIORITY;
|
||||||
|
|
||||||
// enable timer clocking
|
// enable timer clocking
|
||||||
RCC->APB2ENR |= 1<<11;
|
RCC->APB2ENR |= 1<<11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (uint32_t)TIM2:
|
||||||
|
// get back the clock frequency
|
||||||
|
clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
} else if (tmr == TIM2) {
|
// register callback function
|
||||||
clk = sysclks.apb1_timer_freq;
|
callback2 = cb;
|
||||||
|
irqn = TIM2_IRQn;
|
||||||
|
irq_priority = TIM2_IRQ_PRIORITY;
|
||||||
|
|
||||||
// register callback function
|
// enable timer clocking
|
||||||
callback2 = cb;
|
RCC->APB1ENR |= 1<<0;
|
||||||
irqn = TIM2_IRQn;
|
break;
|
||||||
irq_priority = TIM2_IRQ_PRIORITY;
|
|
||||||
|
|
||||||
// enable timer clocking
|
case (uint32_t)TIM3:
|
||||||
RCC->APB1ENR |= 1<<0;
|
// get back the clock frequency
|
||||||
|
clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
} else if (tmr == TIM3) {
|
// register callback function
|
||||||
clk = sysclks.apb1_timer_freq;
|
callback3 = cb;
|
||||||
|
irqn = TIM3_IRQn;
|
||||||
|
irq_priority = TIM3_IRQ_PRIORITY;
|
||||||
|
|
||||||
// register callback function
|
// enable timer clocking
|
||||||
callback3 = cb;
|
RCC->APB1ENR |= 1<<1;
|
||||||
irqn = TIM3_IRQn;
|
break;
|
||||||
irq_priority = TIM3_IRQ_PRIORITY;
|
|
||||||
|
|
||||||
// enable timer clocking
|
case (uint32_t)TIM4:
|
||||||
RCC->APB1ENR |= 1<<1;
|
// get back the clock frequency
|
||||||
|
clk = sysclks.apb1_timer_freq;
|
||||||
|
|
||||||
} else if (tmr == TIM4) {
|
// register callback function
|
||||||
clk = sysclks.apb1_timer_freq;
|
callback4 = cb;
|
||||||
|
irqn = TIM4_IRQn;
|
||||||
|
irq_priority = TIM4_IRQ_PRIORITY;
|
||||||
|
|
||||||
// register callback function
|
// enable timer clocking
|
||||||
callback4 = cb;
|
RCC->APB1ENR |= 1<<2;
|
||||||
irqn = TIM4_IRQn;
|
break;
|
||||||
irq_priority = TIM4_IRQ_PRIORITY;
|
|
||||||
|
|
||||||
// enable timer clocking
|
default:
|
||||||
RCC->APB1ENR |= 1<<2;
|
return -1;
|
||||||
|
}
|
||||||
} else return -1;
|
|
||||||
|
|
||||||
// clear pending interrupts
|
// clear pending interrupts
|
||||||
tmr->SR &= !1;
|
tmr->SR &= !1;
|
||||||
@ -238,15 +258,15 @@ int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb) {
|
|||||||
tmr->CR1 = (1<<7) | (1<<2); //buffering and update settings
|
tmr->CR1 = (1<<7) | (1<<2); //buffering and update settings
|
||||||
tmr->DIER = (1<<0); //Enable interrupts
|
tmr->DIER = (1<<0); //Enable interrupts
|
||||||
|
|
||||||
// set prescaler 1ms
|
// set prescaler 0.5ms
|
||||||
tmr->PSC = 8*(clk/1000)-1; //PSC = clk/f - 1 | don't know why 8 times...
|
tmr->PSC = 8*(clk/2000)-1; //PSC = clk/f - 1 | don't know why 8 times...
|
||||||
|
|
||||||
// set period
|
// set period
|
||||||
if(timer_set_period(tmr,tick_ms)) return -1;
|
if(timer_set_period(tmr, tick_ms)) return -1;
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
NVIC_SetPriority(irqn,irq_priority);
|
NVIC_SetPriority(irqn,irq_priority);
|
||||||
NVIC_EnableIRQ(irqn); //unmask IRQ
|
NVIC_EnableIRQ(irqn); //unmask IRQ
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -254,7 +274,7 @@ int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb) {
|
|||||||
|
|
||||||
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {
|
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {
|
||||||
// set period
|
// set period
|
||||||
tmr->ARR = tick-1; //tickms = (ARR+1)Tpsc
|
tmr->ARR = tick*2-1; //tickms = (ARR+1)Tpsc
|
||||||
|
|
||||||
// force update to reset counter and apply prescaler
|
// force update to reset counter and apply prescaler
|
||||||
tmr->EGR |= 1;
|
tmr->EGR |= 1;
|
||||||
@ -277,19 +297,26 @@ void timer_stop(TIM_TypeDef *tmr) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
int timer_enc_init(TIM_TypeDef* tmr) {
|
int timer_enc_init(TIM_TypeDef* tmr) {
|
||||||
// enable timer
|
// enable timer
|
||||||
if (tmr == TIM1) {
|
switch((uint32_t)tmr) {
|
||||||
RCC->APB2ENR |= 1<<11;
|
case (uint32_t)TIM1:
|
||||||
|
RCC->APB2ENR |= 1<<11;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM2) {
|
case (uint32_t)TIM2:
|
||||||
RCC->APB1ENR |= 1<<0;
|
RCC->APB1ENR |= 1<<0;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM3) {
|
case (uint32_t)TIM3:
|
||||||
RCC->APB1ENR |= 1<<1;
|
RCC->APB1ENR |= 1<<1;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (tmr == TIM4) {
|
case (uint32_t)TIM4:
|
||||||
RCC->APB1ENR |= 1<<2;
|
RCC->APB1ENR |= 1<<2;
|
||||||
|
break;
|
||||||
|
|
||||||
} else return -1; //no such timer
|
default:
|
||||||
|
return -1; //no such timer
|
||||||
|
}
|
||||||
|
|
||||||
//TODO set registers at reset value
|
//TODO set registers at reset value
|
||||||
|
|
||||||
|
|||||||
@ -1,88 +1,89 @@
|
|||||||
#ifndef TIMER_H
|
#ifndef TIMER_H
|
||||||
#define TIMER_H
|
#define TIMER_H
|
||||||
|
|
||||||
#include "../target/stm32f103xb.h"
|
#include "../target/stm32f103xb.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
|
|
||||||
typedef void (*OnTick)(void);
|
typedef void (*OnTick)(void);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** timer_wait_ms
|
/** timer_wait_ms
|
||||||
* wait for ms milliseconds function
|
* wait for ms milliseconds function
|
||||||
*/
|
*/
|
||||||
int timer_wait_ms(TIM_TypeDef *tmr, uint16_t ms, OnTick cb);
|
int timer_wait_ms(TIM_TypeDef *tmr, uint16_t ms, OnTick cb);
|
||||||
|
|
||||||
/** timer_wait_us
|
/** timer_wait_us
|
||||||
* wait for us microseconds function
|
* wait for us microseconds function
|
||||||
*/
|
*/
|
||||||
int timer_wait_us(TIM_TypeDef *tmr, uint16_t us, OnTick cb);
|
int timer_wait_us(TIM_TypeDef *tmr, uint16_t us, OnTick cb);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** timer_tick_init
|
|
||||||
* setup timer to call cb function periodically, each tick_ms
|
/** timer_tick_init
|
||||||
*/
|
* setup timer to call cb function periodically, each tick_ms
|
||||||
int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb);
|
*/
|
||||||
|
int timer_tick_init(TIM_TypeDef *tmr, uint16_t tick_ms, OnTick cb);
|
||||||
/** timer_set_period
|
|
||||||
* change the period, in ms when called after tick_init,
|
/** timer_set_period
|
||||||
* otherwise in whatever unit the timer is configured
|
* change the period, in ms when called after tick_init,
|
||||||
* reset count when used
|
* otherwise in whatever unit the timer is configured
|
||||||
*/
|
* reset count when used
|
||||||
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick);
|
*/
|
||||||
|
int timer_set_period(TIM_TypeDef *tmr, uint16_t tick);
|
||||||
/** timer_start
|
|
||||||
* reset count and start counting
|
/** timer_start
|
||||||
*/
|
* reset count and start counting
|
||||||
void timer_start(TIM_TypeDef *tmr);
|
*/
|
||||||
|
void timer_start(TIM_TypeDef *tmr);
|
||||||
/** timer_stop
|
|
||||||
* stop counting
|
/** timer_stop
|
||||||
*/
|
* stop counting
|
||||||
void timer_stop(TIM_TypeDef *tmr);
|
*/
|
||||||
|
void timer_stop(TIM_TypeDef *tmr);
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** timer_enc_init
|
//------------------------------------------------------------------------------
|
||||||
* setup timer to read encoder output and keep track of it's position in the
|
/** timer_enc_init
|
||||||
* CNT register whithout using CPU time
|
* setup timer to read encoder output and keep track of it's position in the
|
||||||
*/
|
* CNT register whithout using CPU time
|
||||||
int timer_enc_init(TIM_TypeDef* tmr);
|
*/
|
||||||
|
int timer_enc_init(TIM_TypeDef* tmr);
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//#define PWM_CHANNEL_1 0
|
//------------------------------------------------------------------------------
|
||||||
//#define PWM_CHANNEL_2 1
|
//#define PWM_CHANNEL_1 0
|
||||||
//#define PWM_CHANNEL_3 2
|
//#define PWM_CHANNEL_2 1
|
||||||
//#define PWM_CHANNEL_4 3
|
//#define PWM_CHANNEL_3 2
|
||||||
//
|
//#define PWM_CHANNEL_4 3
|
||||||
///** pwm_init
|
//
|
||||||
// * setup pwm timer period, each tick_ms
|
///** pwm_init
|
||||||
// */
|
// * setup pwm timer period, each tick_ms
|
||||||
//int pwm_init(TIM_TypeDef *pwm, uint32_t period_ms, OnTick cb);
|
// */
|
||||||
//
|
//int pwm_init(TIM_TypeDef *pwm, uint32_t period_ms, OnTick cb);
|
||||||
///** pwm_channel_enable
|
//
|
||||||
// * set up pwm channel
|
///** pwm_channel_enable
|
||||||
// */
|
// * set up pwm channel
|
||||||
//int pwm_channel_enable(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle, uint32_t oe);
|
// */
|
||||||
//
|
//int pwm_channel_enable(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle, uint32_t oe);
|
||||||
///** pwm_channel_disable
|
//
|
||||||
// * disable pwm channel
|
///** pwm_channel_disable
|
||||||
// */
|
// * disable pwm channel
|
||||||
//int pwm_channel_disable(TIM_TypeDef *pwm, uint32_t channel);
|
// */
|
||||||
//
|
//int pwm_channel_disable(TIM_TypeDef *pwm, uint32_t channel);
|
||||||
///** pwm_channel_set
|
//
|
||||||
// * set up dutycycle for pwm channel
|
///** pwm_channel_set
|
||||||
// */
|
// * set up dutycycle for pwm channel
|
||||||
//int pwm_channel_set(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle);
|
// */
|
||||||
//
|
//int pwm_channel_set(TIM_TypeDef *pwm, uint32_t channel, uint32_t dutycycle);
|
||||||
///** pwm_start
|
//
|
||||||
// * start counting
|
///** pwm_start
|
||||||
// */
|
// * start counting
|
||||||
//#define pwm_start(pwm) timer_start(pwm)
|
// */
|
||||||
//
|
//#define pwm_start(pwm) timer_start(pwm)
|
||||||
///** pwm_stop
|
//
|
||||||
// * stop and reset counting
|
///** pwm_stop
|
||||||
// */
|
// * stop and reset counting
|
||||||
//#define pwm_stop(pwm) timer_stop(pwm)
|
// */
|
||||||
|
//#define pwm_stop(pwm) timer_stop(pwm)
|
||||||
#endif
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
52
src/main.c
52
src/main.c
@ -1,52 +0,0 @@
|
|||||||
// standard headers
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// driver includes
|
|
||||||
#include "drivers/rcc.h"
|
|
||||||
#include "drivers/io.h"
|
|
||||||
|
|
||||||
Clock_t sysclks;
|
|
||||||
#include "drivers/timer.h"
|
|
||||||
|
|
||||||
extern uint32_t end;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/* static variables */;
|
|
||||||
int val = 0; //debug led
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/* Timer IRQ */
|
|
||||||
static void timeout_cb(void) {
|
|
||||||
io_write(GPIOC, val, PIN_13);
|
|
||||||
val = !val;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/* main function */
|
|
||||||
int main(void) {
|
|
||||||
|
|
||||||
// configure clocks (necessary before using timers)
|
|
||||||
rcc_config_clock(CLOCK_CONFIG_PERFORMANCE, &sysclks);
|
|
||||||
|
|
||||||
// configure GPIO for LED
|
|
||||||
if(io_configure(GPIOC, PIN_13, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0))
|
|
||||||
return -1;
|
|
||||||
io_write(GPIOC, 1, PIN_13);
|
|
||||||
|
|
||||||
// start timed interruption
|
|
||||||
timer_tick_init(TIM2, 1000, timeout_cb);
|
|
||||||
timer_start(TIM2);
|
|
||||||
|
|
||||||
uint32_t test = (uint32_t)(&end);
|
|
||||||
test++;
|
|
||||||
int* tab = (int*)malloc(10*sizeof(int));
|
|
||||||
for(int i=0; i<10; ++i) {
|
|
||||||
tab[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// main loop
|
|
||||||
for(;;);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user