diff --git a/G0:G070/blink/Makefile b/G0:G070/blink/Makefile index a93f0a3..9835964 100644 --- a/G0:G070/blink/Makefile +++ b/G0:G070/blink/Makefile @@ -5,7 +5,7 @@ BOOTSPEED ?= 115200 FAMILY = G0 # MCU code MCU = G070xx -DEFS = -DEBUG -g +DEFS = -DEBUG -g3 # change this linking script depending on particular MCU model, # for example, if you have STM32F103VBT6, you should write: LDSCRIPT = stm32g070xb.ld @@ -134,4 +134,10 @@ boot: $(BIN) @echo " LOAD $(BIN) through bootloader" $(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN) -.PHONY: clean flash boot +openocd: + openocd -f openocd.cfg +dbg: + arm-none-eabi-gdb $(ELF) -ex 'target remote localhost:3333' -ex 'monitor reset halt' + + +.PHONY: clean flash boot openocd dbg diff --git a/G0:G070/blink/README b/G0:G070/blink/README index 3494a6a..221b0c6 100644 --- a/G0:G070/blink/README +++ b/G0:G070/blink/README @@ -1,3 +1,3 @@ Toggle LED on STM32G070-pill depending on user button: -- not pressed - 'SOS' in Morze -- pressed - blink with period of 1 second +- pressed - 'SOS' in Morze +- not pressed - blink with period of 1 second diff --git a/G0:G070/blink/blink.bin b/G0:G070/blink/blink.bin index 8fa372b..6890837 100755 Binary files a/G0:G070/blink/blink.bin and b/G0:G070/blink/blink.bin differ diff --git a/G0:G070/blink/openocd.cfg b/G0:G070/blink/openocd.cfg new file mode 100644 index 0000000..fb036da --- /dev/null +++ b/G0:G070/blink/openocd.cfg @@ -0,0 +1,89 @@ +# script for stm32g0x family + +# +# stm32g0 devices support SWD transports only. +# +source [find interface/stlink.cfg] +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32g0x +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x1000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # Section 37.5.5 - corresponds to Cortex-M0+ + set _CPUTAPID 0x0bc11477 +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME + +# reasonable default +adapter speed 2000 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +proc stm32g0x_default_reset_start {} { + # Reset clock is HSI16 (16 MHz) + adapter speed 2000 +} + +proc stm32g0x_default_examine_end {} { + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP + mmw 0x40015804 0x00000006 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0x40015808 0x00001800 0 +} + +proc stm32g0x_default_reset_init {} { + # Increase clock to 64 Mhz + mmw 0x40022000 0x00000002 0x00000005 ;# FLASH_ACR: Latency = 2 + mww 0x4002100C 0x30000802 ;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2 + mmw 0x40021000 0x01000000 0x00000000 ;# RCC_CR |= PLLON + mmw 0x40021008 0x00000002 0x00000005 ;# RCC_CFGR: SW=PLLRCLK + + # Boost JTAG frequency + adapter speed 4000 +} + +# Default hooks +$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end } +$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start } +$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init } diff --git a/G0:G070/blink/systick_blink.c b/G0:G070/blink/systick_blink.c index c127408..659ecc7 100644 --- a/G0:G070/blink/systick_blink.c +++ b/G0:G070/blink/systick_blink.c @@ -1,11 +1,10 @@ /* - * systick_blink.c + * This file is part of the blink project. + * Copyright 2023 Edward V. Emelianov . * - * Copyright 2017 Edward V. Emelianoff - * - * This program is free software; you can redistribute it and/or modify + * 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 + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,15 +13,13 @@ * 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. + * along with this program. If not, see . */ #include "stm32g0.h" // KEY (intpullup->0) - PC0 -// LED - PC7 +// LED - PC8 static volatile uint32_t blink_ctr = 0; @@ -34,44 +31,48 @@ void sys_tick_handler(void){ /* * Set up timer to fire every x milliseconds */ -static void systick_setup(uint32_t xms){ // xms < 1864!!! +static void systick_setup(uint32_t xms){ // xms < 2098!!! static uint32_t curms = 0; if(curms == xms) return; - // 9MHz - HCLK/8 + // 8MHz - HCLK/8 // this function also clears counter so it starts right away - SysTick_Config(9000 * xms); // arg should be < 0xffffff, so ms should be < 1864 + SysTick_Config(8000 * xms); // arg should be < 0xffffff, so ms should be < 2098 curms = xms; } static void gpio_setup(void){ RCC->IOPENR = RCC_IOPENR_GPIOCEN; // enable PC - // set PC7 as opendrain output, PC0 is pullup input - GPIOC->MODER = GPIO_MODER_MODER7_O; - GPIOC->PUPDR = GPIO_PUPDR_PUPD0; - GPIOC->OTYPER = GPIO_OTYPER_OT7; + // set PC8 as opendrain output, PC0 is pullup input, other as default (AIN) + GPIOC->MODER = (0xffffffff & ~(GPIO_MODER_MODE8 | GPIO_MODER_MODE0)) | GPIO_MODER_MODER8_O; + GPIOC->PUPDR = GPIO_PUPDR0_PU; // pullup + GPIOC->OTYPER = GPIO_OTYPER_OT8; // open drain } static const uint32_t L[] = {125,100,125,100,125,200, 350,100,350,100,350,200, 125,100,125,100,125, 1000}; int main(void){ StartHSE(); - //StartHSI48(); gpio_setup(); - /* 500ms ticks => 1000ms period => 1Hz blinks */ - systick_setup(100); + systick_setup(500); + uint32_t M = 0; + int pressed = 0; /* Do nothing in main loop */ while (1){ - if(pin_read(GPIOC, 1<<7)){ // key not pressed - 'sos' - uint32_t T = blink_ctr % 18; - systick_setup(L[T]); - if(T & 1) pin_clear(GPIOC, 1<<7); - else pin_set(GPIOC, 1<<7); + if(pin_read(GPIOC, 1<<0) == 0){ // key not pressed - 'sos' + pressed = 1; + systick_setup(L[M]); + if(M & 1) pin_set(GPIOC, 1<<8); + else pin_clear(GPIOC, 1<<8); + if(++M == 18) M = 0; }else{ // key pressed - blink with period of 1s - systick_setup(500); - if(blink_ctr & 1) pin_clear(GPIOC, 1<<7); - else pin_set(GPIOC, 1<<7); - + if(pressed){ + M = 0; + pressed = 0; + systick_setup(500); + } + if(blink_ctr & 1) pin_set(GPIOC, 1<<8); + else pin_clear(GPIOC, 1<<8); } } } diff --git a/G0:G070/inc/Fx/stm32g0.h b/G0:G070/inc/Fx/stm32g0.h index ec0b039..d88853d 100644 --- a/G0:G070/inc/Fx/stm32g0.h +++ b/G0:G070/inc/Fx/stm32g0.h @@ -29,8 +29,9 @@ /************************* RCC *************************/ // reset clocking registers -TRUE_INLINE void sysreset(void){ // do nothing +/* TRUE_INLINE void sysreset(void){ // do nothing } +*/ /* * R=2..8, Q=2..8, P=2..32; N=8..86, M=1..8 @@ -40,23 +41,58 @@ TRUE_INLINE void sysreset(void){ // do nothing * fpllp = fvco/P (<=122MHz) -> P(72)=2 * fpllq = fvco/Q (<=128MHz) -> Q(48)=3 * fpllr = fvco/R (<=64MHz) -> R(48)=3 - * AHB prescaler (72MHz) = 144/72 = 2 - * APB prescaler (72MHz) = 72/72 = 1 + * AHB prescaler (36MHz) = 72/36 = 2 + * APB prescaler (36MHz) = 36/36 = 1 + * + * fp=fq=fr=fsys=64MHz => M=1, N=8, P=1, Q=1, R=1 */ +#ifndef PLLN +#define PLLN 16 +#endif +#ifndef PLLM +#define PLLM 1 +#endif +#ifndef PLLP +#define PLLP 2 +#endif +#ifndef PLLQ +#define PLLQ 2 +#endif +#ifndef PLLR +#define PLLR 2 +#endif + #define WAITWHILE(x) do{StartUpCounter = 0; while((x) && (++StartUpCounter < 0xffffff)){nop();}}while(0) -TRUE_INLINE void StartHSE(){ +TRUE_INLINE void StartHSEHSI(int isHSE){ uint32_t StartUpCounter; RCC->CR &= ~RCC_CR_PLLON; // disable PLL WAITWHILE(RCC->CR & RCC_CR_PLLRDY); // wait while PLL on - RCC->CR |= RCC_CR_HSEON; - WAITWHILE(!(RCC->CIFR & RCC_CIFR_HSERDYF)); // wait while HSE isn't on - RCC->CICR = RCC_CICR_HSERDYC; // clear rdy flag + if(isHSE){ + RCC->CR |= RCC_CR_HSEON; + WAITWHILE(!(RCC->CR & RCC_CR_HSERDY)); // wait while HSE isn't on + }else RCC->CR |= RCC_CR_HSION; + RCC->APBENR1 |= RCC_APBENR1_PWREN; + // Enable high performance mode + PWR->CR1 = PWR_CR1_VOS_0; + WAITWHILE(PWR->SR2 & PWR_SR2_VOSF); + if(isHSE){ + RCC->PLLCFGR = ((PLLR-1)<<29) | ((PLLQ-1)<<25) | ((PLLP-1)<<17) | (PLLN<<8) | ((PLLM-1)<<4) + | RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLPEN /* | RCC_PLLCFGR_PLLQEN */ + | RCC_PLLCFGR_PLLSRC_HSE; + }else{ // 64MHz from HSI16 + RCC->PLLCFGR = (8<<8) | (1<<4) + | RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLPEN /* | RCC_PLLCFGR_PLLQEN */ + | RCC_PLLCFGR_PLLSRC_HSI; + } RCC->CR |= RCC_CR_PLLON; - RCC->PLLCFGR = (3<<29) | (3<<25) | (2<<17) | (18<<8) | (1<<4) | RCC_PLLCFGR_PLLSRC_HSE; - RCC->CFGR = RCC_CFGR_HPRE_3 | RCC_CFGR_SW_1; // set sysclk switch to pll, set prescalers - WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); // wait until status changed + WAITWHILE(!(RCC->CR & RCC_CR_PLLRDY)); + FLASH->ACR |= FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_1; + RCC->CFGR = RCC_CFGR_SW_1; // set sysclk switch to pll } +#define StartHSE() do{StartHSEHSI(1);}while(0) +#define StartHSI() do{StartHSEHSI(0);}while(0) + /************************* GPIO *************************/ /******************* Bit definition for GPIO_MODER register *****************/ diff --git a/G0:G070/inc/cm/core_cm0plus.h b/G0:G070/inc/cm/core_cm0plus.h index 4d7facf..fb760f8 100644 --- a/G0:G070/inc/cm/core_cm0plus.h +++ b/G0:G070/inc/cm/core_cm0plus.h @@ -800,7 +800,7 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) SysTick->LOAD = ticks - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick->CTRL = //SysTick_CTRL_CLKSOURCE_Msk | // clk/8 SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ diff --git a/G0:G070/inc/ld/stm32g070xb.ld b/G0:G070/inc/ld/stm32g070xb.ld index 2c3b0f8..557dc2b 100644 --- a/G0:G070/inc/ld/stm32g070xb.ld +++ b/G0:G070/inc/ld/stm32g070xb.ld @@ -1,5 +1,3 @@ -/* Linker script for STM32F030f4, 16K flash, 4K RAM. */ - /* Define memory regions. */ MEMORY { diff --git a/G0:G070/inc/startup/vector.c b/G0:G070/inc/startup/vector.c index 04dfbb6..f4080b4 100644 --- a/G0:G070/inc/startup/vector.c +++ b/G0:G070/inc/startup/vector.c @@ -148,9 +148,6 @@ void WEAK __attribute__ ((naked)) __attribute__ ((noreturn)) reset_handler(void) char *dst = &_sdata; char *src = &_ldata; - // enable 8-byte stack alignment to comply with AAPCS - //SCB->CCR |= 0x00000200; - // copy initialized variables data while ( dst < &_edata ) { *dst++ = *src++; }