boost converter

This commit is contained in:
kraus 2018-10-12 15:33:54 +02:00
parent 4db469252f
commit 96405a3438
4 changed files with 589 additions and 1 deletions

View File

@ -4,7 +4,7 @@
Assumes LED at Pin 6, GPIO PA0
*/
#include "stm32l031xx.h"
#include "stm32l011xx.h"
volatile unsigned long SysTickCount = 0;

View File

@ -0,0 +1,151 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
# GCCBINPATH:=/usr/bin/ <<<< Ubuntu version is broken at the moment
GCCBINPATH:=/home/kraus/prg/gcc-arm-none-eabi-7-2018-q2-update/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=blink
# The source files of the project
CSRC:=$(wildcard *.c)
SSRC:=$(wildcard ../stm32l0xx/src/*.s)
# The CPU architecture (will be used for -mcpu)
# for the LPC824, can we use "cortex-m0plus"?
MCPU:=cortex-m0plus
# Include directory for the system include files
SYSINC:=../stm32l0xx/inc
SYSSRC:=$(wildcard ../stm32l0xx/src/*.c)
# Include directory for the u8g2 include files
#U8G2INC:=../../../../csrc/
#U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=stm32l011x4.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(CSRC:.c=.o) $(SSRC:.s=.o) $(SYSSRC:.c=.o)
# $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by arm tools
AS:=$(GCCBINPATH)arm-none-eabi-as
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -DSTM32L011xx
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
#COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
COMMON_FLAGS += -ffunction-sections -fdata-sections
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nosys.specs -lc -lc -lnosys -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: $(DISNAME) $(HEXNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
# stm32flash v0.5 does not support STM32L011, so use the latest snapshot
upload: $(DISNAME) $(HEXNAME) $(ELFNAME)
~/git/stm32flash-code/stm32flash -e 127 -g 0 -w $(HEXNAME) -v /dev/ttyUSB0
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) libssp.a libssp_nonshared.a
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@ -0,0 +1,192 @@
/*
boost converter project for the STM32L011x4
STM32L011D3P D=14Pin 3=8KB P=TTSOP
STM32L011D4P D=14Pin 4=16KB P=TTSOP
STM32L011F3P F=20Pin 3=8KB P=TTSOP
STM32L011F4P F=20Pin 4=16KB P=TTSOP
TSSOP20:
PB9/BOOT 1 20 PA14
PC14 2 19 PA13
PC15 3 18 PA10 TIM21_CH1, TIM2_CH3
Reset 4 17 PA9 TIM21_CH2
VDDA 5 16 VDD
PA0 C1- 6 15 GND
PA1 C1+ 7 14 PB1 ADC9
PA2 C2- TX 8 13 PA7 C2+
PA3 C2+ RX 9 12 PA6 ADC6
PA4 C1- C2- 10 11 PA5 C1- C2-
Comp 2:
Input: REFINT /4
Input: PA7 (C2+),
Output: PA9 (TIM21_CH2)
Comp 1:
Input: REFINT
Input: PA1 (C1+)
Output: PA10 (TIM2_CH3)
*/
#include "stm32l011xx.h"
/*===============================================*/
/*
systick IRQ
*/
volatile unsigned long SysTickCount = 0;
void __attribute__ ((interrupt, used)) SysTick_Handler(void)
{
SysTickCount++;
if ( SysTickCount & 1 )
GPIOA->BSRR = GPIO_BSRR_BS_0; /* atomic set PA0 */
else
GPIOA->BSRR = GPIO_BSRR_BR_0; /* atomic clr PA0 */
}
/*===============================================*/
/*
boost converter
PA6=Output to N-MOS Gate
PA7=Reference Input
*/
void boost_converter(void)
{
/* assumes, that SYSCFG_CRGR3 is not locked */
/* assumes, that COMP2 is not locked */
/* setup internal reference (ca. 1.2V) */
SYSCFG->CFGR3 |= SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP; /* enable VREFINT during low power mode */
while( (SYSCFG->CFGR3 & SYSCFG_CFGR3_VREFINT_RDYF) == 0 ) /* wait for VREFINT until it becomes ready */
;
/* configure PA7 as COMP2 Plus input */
/* GPIO has to be in input state without any pull up/down resistor: This is default, so nothing needs to be done here */
/* configure PA9 as TIM21 output */
GPIOA->MODER &= ~GPIO_MODER_MODE0; /* clear mode */
GPIOA->MODER |= GPIO_MODER_MODE9_0; /* Output mode */
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_9; /* no Push/Pull */
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED9; /* low speed */
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD9; /* no pullup/pulldown */
GPIOA->BSRR = GPIO_BSRR_BR_9; /* atomic clr */
GPIOA->AFR[1] &= GPIO_AFRH_AFRH1_Msk;
GPIOA->AFR[1] |= 5<<GPIO_AFRH_AFRH1_Pos; /* AF5 selects TIM21 */
/* setup COMP2 */
/*
COMP2 has only one register: CSR
Bit 31: Lock bit, will lock CSR until next reset if set to 1
Bit 30: Output value, considering polarity
Bit 15: Polarity, 0: Not inverted
Bits 10:8: Plus input
000: PA3
001: PB4
010: PB5
011: PB6
100: PB7
101: PA7 (for category 1 devices only)
Bits 6:4: Minus input
000: VREFINT
001: PA2
010: PA4
011: PA5
100: 1/4 VREFINT
101: 1/2 VREFINT
110: 3/4 VREFINT
111: PB
Bit 3: Speed selection, 0: Low speed
Bit 0: Enable
*/
/* select PA7 as positive input --> 101, only available for the STM32L011 */
COMP2->CSR &= ~(uint32_t)COMP_CSR_COMP2INPSEL;
COMP2->CSR |= COMP_CSR_COMP2INPSEL_0 | COMP_CSR_COMP2INPSEL_2;
/*
0.306V
20mA 15 Ohm 20.4mA
20mA 18 Ohm 17mA
350mA 1 Ohm 306mA --> 300mWatt
*/
/* select 1/4 internal reference voltage --> 0.306 Volt -->100 */
COMP2->CSR &= ~(uint32_t)COMP_CSR_COMP2INNSEL;
COMP2->CSR |= COMP_CSR_COMP2INNSEL_2;
/* invert polarity */
COMP2->CSR |= COMP_CSR_COMP2POLARITY;
/* comparator enable */
COMP2->CSR |= COMP_CSR_COMP2EN;
/* setup PWM mode for TIM21 */
/* configure output compare for channel 2 of TIM21 */
TIM21->CCMR1 &= ~(uint32_t)TIM_CCMR1_CC2S;
/* configure pwm mode 1 */
TIM21->CCMR1 &= ~(uint32_t)TIM_CCMR1_OC2M; /* clear mode to 000 */
TIM21->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; /* pwm mode 1 (110) */
TIM21->CCMR1 |= TIM_CCMR1_OC2PE; /* load modified CCR1 during update event only */
TIM21->PSC = 0; /* run with max speed (2 MHz after reset) */
TIM21->ARR = 20; /* period of 20 clocks (100KHz if sys clock is not modified */
TIM21->CCR2 = 10; /* a value between 0 and ARR, which defines the duty cycle */
/* output the result of channel 2 to PA9 */
TIM21->CCER |= TIM_CCER_CC2E;
/* do not invert the output polarity (this is also the default value) */
TIM21->CCER &= ~(uint32_t)TIM_CCER_CC2P;
/* use up counter (this is also the default value) */
TIM21->CR1 &= ~(uint32_t)TIM_CR1_DIR;
/* do not use "one pulse mode" (continues mode, this is also the default value) */
TIM21->CR1 &= ~(uint32_t)TIM_CR1_OPM;
/* always generate an update event (this is also default) */
TIM21->CR1 &= ~(uint32_t)TIM_CR1_UDIS;
/* update event can be caused by UG bit and overflow (this is default) */
TIM21->CR1 &= ~(uint32_t)TIM_CR1_URS;
/* enable the counter */
TIM21->CR1 |= TIM_CR1_CEN;
}
int main()
{
RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
RCC->APB2ENR |= RCC_APB2ENR_ADCEN;
RCC->APB2ENR |= RCC_APB2ENR_TIM21EN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
__NOP();
__NOP();
GPIOA->MODER &= ~GPIO_MODER_MODE0; /* clear mode for PA0 */
GPIOA->MODER |= GPIO_MODER_MODE0_0; /* Output mode for PA0 */
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_0; /* no Push/Pull for PA0 */
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED0; /* low speed for PA0 */
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD0; /* no pullup/pulldown for PA0 */
GPIOA->BSRR = GPIO_BSRR_BR_0; /* atomic clr PA0 */
-
SysTick->LOAD = 2000*500 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 7; /* enable, generate interrupt (SysTick_Handler), do not divide by 2 */
for(;;)
;
}

View File

@ -0,0 +1,245 @@
/*
stm32l011x4.ld
Modified for stm32l0 from the original nokeep.ld script from the
arm-none-eabi examples by olikraus@gmail.com
Assuming, that the original nokeep.ld file is available under
the GNU General Public License, this file is available under the
same license.
There are three modifications:
1. Provide symbols for the stm32l0 startup code
The following symbols are required for the stm32l0 startup
code (e.g. startup_stm32l011xx.s)
_sidata start address for the initialization values of the .data section
_sdata start address for the .data section. defined in linker script
_edata end address for the .data section. defined in linker script
_sbss start address for the .bss section. defined in linker script
_ebss end address for the .bss section. defined in linker script
_estack top address of the stack
2. Stack size estimation / calculation
_Stack_Size has been added to allow better stack size calculation
3. KEEP keywords
Additionall KEEPs added for .init and .fini. Without this KEEP the
generated code will not work, because of the missing _init function.
4. Bugfix: Allign the end of the flash area
*/
_Stack_Size = 0x400; /* stm32l0: estimated amount of stack */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 16K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
/* the st32l0 startup code calls __libc_init_array, which calls the _init */
/* ... sooo.... better keep the init and fini sections */
KEEP ( *(.init) )
KEEP ( *(.fini) )
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
*(.eh_frame*)
/* allign the end of the flash area */
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
_sidata = .; /* for stm32l0 startup code */
.data : AT (__etext)
{
__data_start__ = .;
_sdata = .; /* for stm32l0 startup code */
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
*(.preinit_array)
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
*(SORT(.init_array.*))
*(.init_array)
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.jcr)
. = ALIGN(4);
/* All data end */
__data_end__ = .;
_edata = .; /* for stm32l0 startup code */
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
_sbss = .; /* for stm32l0 startup code */
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
_ebss = .; /* for stm32l0 startup code */
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
. = . + _Stack_Size; /* estimated stack size */
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
_estack = __StackTop; /* for stm32l0 startup code */
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}