* add submodules and config for g0 port

* Rename FLASH_SIZE to JD_FLASH_SIZE (conflict with HAL)

* Fix a number of peripherals for G0

* Disable PLL switching on USART2 (also on F0)

* Fix RTC for G0

* UART and BL G0 fixes

* Disable namestore (unused) on G0

* Move device id to OTP

* Fix uart in bl

* Fix cpu_mhz init

* Real Time Clock has a Clock on G0!

* Fix temp reading on g0

* Fixup board init code

* Make it build on F0 again

* Adjust start delays
This commit is contained in:
Michał Moskal 2021-03-09 18:50:43 +01:00 коммит произвёл GitHub
Родитель 48be0d64ef
Коммит 86de72c8dc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 297 добавлений и 74 удалений

6
.gitmodules поставляемый
Просмотреть файл

@ -7,3 +7,9 @@
[submodule "stm32/cmsis_device_f0"]
path = stm32/cmsis_device_f0
url = https://github.com/STMicroelectronics/cmsis_device_f0
[submodule "stm32/cmsis_device_g0"]
path = stm32/cmsis_device_g0
url = https://github.com/STMicroelectronics/cmsis_device_g0
[submodule "stm32/stm32g0xx_hal_driver"]
path = stm32/stm32g0xx_hal_driver
url = https://github.com/STMicroelectronics/stm32g0xx_hal_driver

Просмотреть файл

@ -47,13 +47,22 @@ int main(void) {
__disable_irq();
clk_setup_pll();
#if USART_IDX==1
#if USART_IDX == 1
#ifdef STM32G0
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
#else
LL_APB1_GRP1_EnableClock(LL_APB1_GRP2_PERIPH_USART1);
#endif
#if USART_IDX==2
#endif
#if USART_IDX == 2
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
#endif
#ifdef STM32G0
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM17 | LL_APB2_GRP1_PERIPH_ADC);
#else
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM17 | LL_APB1_GRP2_PERIPH_ADC1);
#endif
ctx_t *ctx = &ctx_;
@ -67,6 +76,16 @@ int main(void) {
uint32_t r0 = bl_adc_random_seed();
ctx->randomseed = r0;
#ifdef OTP_DEVICE_ID_ADDR
if (*(uint32_t *)OTP_DEVICE_ID_ADDR + 1 == 0) {
uint32_t r1 = bl_adc_random_seed();
r0 &= ~0x02000000; // clear "universal" bit
BL_DEVICE_ID = ((uint64_t)r0 << 32) | r1;
flash_program((void *)OTP_DEVICE_ID_ADDR, &BL_DEVICE_ID, 8);
} else {
BL_DEVICE_ID = *(uint64_t *)OTP_DEVICE_ID_ADDR;
}
#else
if ((bl_dev_info.device_id0 + 1) == 0) {
if (app_dev_info.magic == DEV_INFO_MAGIC && app_dev_info.device_id0 &&
(app_dev_info.device_id0 + 1)) {
@ -80,6 +99,7 @@ int main(void) {
} else {
BL_DEVICE_ID = bl_dev_info.device_id;
}
#endif
BL_DEVICE_ID ^= 1; // use different dev-id for application and bootloader
@ -97,7 +117,7 @@ int main(void) {
#else
(void)app_valid;
#endif
ctx->app_start_time = 0x80000000;
ctx->app_start_time = 0x80000000;
while (1) {
uint32_t now = ctx->now = tim_get_micros();

Просмотреть файл

@ -15,7 +15,7 @@ static int setup_tx(ctx_t *ctx, int cmd, const void *data, int size) {
}
static const uint32_t bl_ad_data[] = {JD_SERVICE_CLASS_BOOTLOADER, BL_PAGE_SIZE,
FLASH_SIZE - BL_SIZE, 0};
JD_FLASH_SIZE - BL_SIZE, 0};
void bl_process(ctx_t *ctx) {
if (ctx->chunk_no == 0xff && setup_tx(ctx, JD_BOOTLOADER_CMD_PAGE_DATA, &ctx->session_id, 12) == 0)

Просмотреть файл

@ -1,5 +1,10 @@
#include "bl.h"
#ifdef USART_ISR_TXE_TXFNF
#define USART_ISR_TXE USART_ISR_TXE_TXFNF
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#endif
#define PORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400 * (pin >> 4))))
#define PIN(pin) (1 << ((pin)&0xf))
@ -49,9 +54,9 @@ void uart_init(ctx_t *ctx) {
#endif
#ifdef LL_USART_FIFOTHRESHOLD_1_8
LL_USART_SetTXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
LL_USART_SetRXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
LL_USART_DisableFIFO(USARTx);
//LL_USART_SetTXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
//LL_USART_SetRXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
//LL_USART_DisableFIFO(USARTx);
#endif
LL_USART_ConfigHalfDuplexMode(USARTx);
@ -133,7 +138,7 @@ int uart_start_tx(ctx_t *ctx, const void *data, uint32_t numbytes) {
ctx->uart_bytesleft = numbytes;
ctx->uart_mode = UART_MODE_TX;
target_wait_us(37);
target_wait_us(40);
return 0;
}

Просмотреть файл

@ -4,7 +4,7 @@
#include "pinnames.h"
uint64_t hw_device_id(void) {
return app_dev_info.device_id;
return APP_DEVICE_ID;
}
uint32_t app_get_device_class(void) {

Просмотреть файл

@ -74,5 +74,12 @@ struct app_top_handlers {
#define app_dev_info app_handlers->devinfo
#ifndef BL
#define bl_info (*((struct bl_info_block *)(0x8000000 + FLASH_SIZE - BL_SIZE)))
#define bl_info (*((struct bl_info_block *)(0x8000000 + JD_FLASH_SIZE - BL_SIZE)))
#endif
#ifdef STM32G0
#define OTP_DEVICE_ID_ADDR (0x1FFF7000 + 1024 - 8)
#define APP_DEVICE_ID *(uint64_t *)OTP_DEVICE_ID_ADDR
#else
#define APP_DEVICE_ID app_dev_info.device_id
#endif

Просмотреть файл

@ -1,5 +1,7 @@
#include "lib.h"
// SPI-Jacdac bridge (not used)
#ifdef BRIDGEQ
struct srv_state {

Просмотреть файл

@ -28,3 +28,10 @@
#define FIRMWARE_IDENTIFIER(dev_class, dev_class_name) \
const char app_dev_class_name[] = dev_class_name;
#endif
#ifdef BL
void board_init(void);
#else
#define PROFILE_INIT 1
#include "board.h" // again
#endif

Просмотреть файл

@ -1,8 +1,13 @@
#include "lib.h"
// (not used)
// STM32G0 requires 8-byte aligned flash writes
#ifndef STM32G0
#define MAGIC 0xe233b285
#define SETTINGS_SIZE 1024
#define SETTINGS_START (0x08000000 + (FLASH_SIZE - BL_SIZE - SETTINGS_SIZE))
#define SETTINGS_START (0x08000000 + (JD_FLASH_SIZE - BL_SIZE - SETTINGS_SIZE))
extern uint32_t __etext;
@ -137,3 +142,5 @@ const char *ns_get(uint64_t key) {
return NULL;
return ex->name;
}
#endif

Просмотреть файл

@ -174,8 +174,19 @@ static const uint32_t channels_PB[] = {
#endif
#endif
#ifdef STM32G0
#define TS_CAL1 *(uint16_t *)0x1FFF75A8 // @30C
#ifdef STM32G031xx
#define TS_CAL2 *(uint16_t *)0x1FFF75CA // @130C (not defined on G030)
#endif
#endif
uint16_t adc_read_temp(void) {
#ifdef STM32G0
set_sampling_time(LL_ADC_SAMPLINGTIME_160CYCLES_5);
#else
set_sampling_time(LL_ADC_SAMPLINGTIME_71CYCLES_5); // min. sampling time for temp is 4us
#endif
set_temp_ref(1);
set_channel(LL_ADC_CHANNEL_TEMPSENSOR);
@ -184,15 +195,20 @@ uint16_t adc_read_temp(void) {
LL_ADC_Disable(ADC1);
set_temp_ref(0);
#if defined(STM32F030x6) || defined(STM32F030x8)
#if defined(STM32F030x6) || defined(STM32F030x8)
return ((TS_CAL1 - r) * 1000) / 5336 + 30;
#elif defined(STM32F031x6) || defined(STM32F042x6)
return ((110 - 30) * (r - TS_CAL1)) / (TS_CAL2 - TS_CAL1) + 30;
#elif defined(STM32G031xx)
// 33/30 - because factory measurements are done at 3.0V and we're running at 3.3V
return ((130 - 30) * 33 * (r - TS_CAL1)) / (30 * TS_CAL2 - TS_CAL1) + 30;
#else
#error "check datasheet!"
// copied TEMP slope from G031; hopefully that works for G030
return ((130 - 30) * 33 * (r - TS_CAL1)) / (30 * 343) + 30;
#endif
}
static uint32_t pin_channel(uint8_t pin) {
if (pin >> 4 == 0) {
if ((pin & 0xf) >= sizeof(channels_PA) / sizeof(channels_PA[0]))
@ -219,7 +235,11 @@ void adc_prep_read_pin(uint8_t pin) {
pin_setup_analog_input(pin);
#ifdef STM32G0
set_sampling_time(LL_ADC_SAMPLINGTIME_39CYCLES_5);
#else
set_sampling_time(LL_ADC_SAMPLINGTIME_41CYCLES_5);
#endif
set_channel(chan);
}

1
stm32/cmsis_device_g0 Submodule

@ -0,0 +1 @@
Subproject commit 857e03d94c18008e4df98bb08431df7d74726222

Просмотреть файл

@ -7,6 +7,10 @@ static void _check_line(int ln) {
callbacks[ln]();
}
#ifdef STM32G0
#define PR FPR1
#endif
#define check_line(ln) \
if (lines & (1 << (ln))) \
_check_line(ln)

Просмотреть файл

@ -1,5 +1,9 @@
#include "jdstm.h"
#ifdef STM32G0
#define FLASH_SR_BSY FLASH_SR_BSY1
#endif
#define WAIT_BUSY() \
while (FLASH->SR & FLASH_SR_BSY) \
;
@ -12,6 +16,10 @@ static void unlock(void) {
}
FLASH->SR = FLASH_SR_EOP;
FLASH->CR &= ~(FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_STRT);
#ifdef STM32G0
// this is required for the EOP/error bit to be set
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
#endif
}
static void lock(void) {
@ -28,28 +36,55 @@ static void check_eop(void) {
}
void flash_program(void *dst, const void *src, uint32_t len) {
#ifdef STM32G0
if ((((uint32_t)dst) & 7) || (((uint32_t)src) & 7) || (len & 7))
jd_panic();
#else
if ((((uint32_t)dst) & 1) || (((uint32_t)src) & 1) || (len & 1))
jd_panic();
#endif
unlock();
FLASH->CR |= FLASH_CR_PG; // enable programming
len >>= 1;
#ifdef STM32G0
len >>= 3;
__IO uint32_t *dp = dst;
const uint32_t *sp = src;
while (len--) {
int erased = dp[0] + 1 == 0 && dp[1] + 1 == 0;
if (!erased && (sp[0] || sp[1]))
jd_panic();
WAIT_BUSY();
dp[0] = sp[0];
dp[1] = sp[1];
check_eop();
dp += 2;
sp += 2;
}
#else
len >>= 1;
while (len--) {
*(__IO uint16_t *)(dst) = *(uint16_t *)src;
check_eop();
dst = (uint16_t *)dst + 1;
src = (uint16_t *)src + 1;
}
#endif
lock();
}
void flash_erase(void *page_addr) {
unlock();
#ifdef STM32G0
uint32_t addrmask = (((uint32_t)page_addr >> 11) << FLASH_CR_STRT_Pos) & FLASH_CR_PNB;
FLASH->CR = (FLASH->CR & ~FLASH_CR_PNB) | FLASH_CR_PER | addrmask;
#else
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = (uint32_t)page_addr;
#endif
FLASH->CR |= FLASH_CR_STRT;
check_eop();
lock();

Просмотреть файл

@ -2,8 +2,20 @@
#ifdef PIN_SDA
#ifndef I2C_IDX
#define I2C_IDX 1
#endif
#if I2C_IDX == 1
#define I2Cx I2C1
#define I2C_CLK LL_APB1_GRP1_PERIPH_I2C1
#define I2C_CLK_SRC LL_RCC_I2C1_CLKSOURCE_HSI
#elif I2C_IDX == 2
#define I2Cx I2C2
#define I2C_CLK LL_APB1_GRP1_PERIPH_I2C2
// only G0Bx and G0Cx support this - we don't really want PCLK source, so in reality only I2C1 is supported
#define I2C_CLK_SRC LL_RCC_I2C2_CLKSOURCE_HSI
#endif
#ifndef I2C_FAST_MODE
#define I2C_FAST_MODE 1
@ -27,6 +39,15 @@
#endif
#endif
#ifdef STM32G0
// 25.4.11 I2C_TIMINGR register configuration examples
#if I2C_FAST_MODE
#define I2C_TIMING 0x10320309
#else
#define I2C_TIMING 0x30420F13
#endif
#endif
static void setup_pin(uint8_t pin) {
pin_setup_output_af(pin, I2C_AF);
LL_GPIO_SetPinOutputType(PIN_PORT(pin), PIN_MASK(pin), LL_GPIO_OUTPUT_OPENDRAIN);
@ -36,7 +57,7 @@ static void setup_pin(uint8_t pin) {
void i2c_init(void) {
setup_pin(PIN_SDA);
setup_pin(PIN_SCL);
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_HSI);
LL_RCC_SetI2CClockSource(I2C_CLK_SRC);
LL_APB1_GRP1_EnableClock(I2C_CLK);
LL_I2C_Disable(I2Cx);
LL_I2C_SetTiming(I2Cx, I2C_TIMING);
@ -45,6 +66,8 @@ void i2c_init(void) {
#ifdef STM32F0
#define CYCLES_PER_MS (77 * cpu_mhz)
#elif defined(STM32G0)
#define CYCLES_PER_MS (100 * cpu_mhz) // TODO measure this!
#else
#error "measure CYCLES_PER_MS"
#endif

Просмотреть файл

@ -23,6 +23,7 @@ static void enable_nrst_pin(void) {
DMESG("check NRST", FLASH->OPTR & FLASH_OPTR_NRST_MODE);
// this is default production value, but we check it anyways
if (FLASH->OPTR & FLASH_OPTR_NRST_MODE_0)
return;
@ -100,6 +101,7 @@ void clk_setup_pll(void) {
}
void clk_set_pll(int on) {
#ifndef DISABLE_PLL
if (!on) {
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_HSI)
@ -117,29 +119,30 @@ void clk_set_pll(int on) {
tim_update_prescaler();
// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
#endif
}
uint8_t cpu_mhz;
void SystemClock_Config(void) {
cpu_mhz = HSI_MHZ;
// LL_InitTick(cpu_mhz * 1000000, 1000U);
// LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
enable_nrst_pin();
}
uint8_t cpu_mhz = HSI_MHZ;
void SystemInit(void) {
// on G0 this is called before global variables are initialized
// also, they will be initialized after this is finished, so any writes to globals will be lost
#ifdef STM32G0
SCB->VTOR = FLASH_BASE;
#endif
SCB->VTOR = FLASH_BASE; // needed?
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA | LL_IOP_GRP1_PERIPH_GPIOB |
LL_IOP_GRP1_PERIPH_GPIOC);
#else
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA | LL_AHB1_GRP1_PERIPH_GPIOB |
LL_AHB1_GRP1_PERIPH_GPIOC | LL_AHB1_GRP1_PERIPH_GPIOF);
#endif
SystemClock_Config();
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
#ifdef BOARD_STARTUP_CODE
BOARD_STARTUP_CODE;
#endif
enable_nrst_pin();
}

6
stm32/mk/STM32G031x8.mk Normal file
Просмотреть файл

@ -0,0 +1,6 @@
RAM_SIZE = 8
FLASH_SIZE ?= 64
BL_SIZE ?= 4
PAGE_SIZE = 2048
DEFINES += -DSTM32G031xx
STARTUP_FILE = $(PLATFORM)/cmsis_device_g0/Source/Templates/gcc/startup_stm32g031xx.s

Просмотреть файл

@ -9,7 +9,6 @@ HALPREF = $(PLATFORM)/stm32f0xx_hal_driver/Src
HALSRC = \
$(HALPREF)/stm32f0xx_ll_adc.c \
$(HALPREF)/stm32f0xx_ll_comp.c \
$(HALPREF)/stm32f0xx_ll_crc.c \
$(HALPREF)/stm32f0xx_ll_crs.c \
$(HALPREF)/stm32f0xx_ll_dac.c \
$(HALPREF)/stm32f0xx_ll_dma.c \
@ -35,7 +34,7 @@ CPPFLAGS += \
-I$(PLATFORM)/cmsis_device_f0/Include \
-I$(PLATFORM)/cmsis_core/Include
DEFINES += -DUSE_FULL_LL_DRIVER -DSTM32$(SERIES)
DEFINES += -D$(MCU) -DFLASH_SIZE="1024*$(FLASH_SIZE)" -DFLASH_PAGE_SIZE=$(PAGE_SIZE) -DBL_SIZE="1024*$(BL_SIZE)"
DEFINES += -D$(MCU) -DJD_FLASH_SIZE="1024*$(FLASH_SIZE)" -DFLASH_PAGE_SIZE=$(PAGE_SIZE) -DBL_SIZE="1024*$(BL_SIZE)"
include $(PLATFORM)/mk/$(MCU).mk

Просмотреть файл

@ -1,26 +1,58 @@
SERIES = G0
CFLAGS += -mcpu=cortex-m0plus
OPENOCD ?= ./scripts/openocd -s ./scripts -f cmsis-dap.cfg -f stm32g0x.cfg
#OPENOCD ?= openocd -f interface/stlink-v2-1.cfg -f target/stm32g0x.cfg
#OPENOCD ?= ./scripts/openocd -s ./scripts -f cmsis-dap.cfg -f stm32g0x.cfg
OPENOCD ?= openocd -f interface/cmsis-dap.cfg -f target/stm32g0x.cfg
HALPREF = $(DRV)/STM32G0xx_HAL_Driver/Src
HALPREF = $(PLATFORM)/stm32g0xx_hal_driver/Src
HALSRC = \
$(HALPREF)/stm32g0xx_ll_adc.c \
$(HALPREF)/stm32g0xx_ll_comp.c \
$(HALPREF)/stm32g0xx_ll_crc.c \
$(HALPREF)/stm32g0xx_ll_crs.c \
$(HALPREF)/stm32g0xx_ll_dac.c \
$(HALPREF)/stm32g0xx_ll_dma.c \
$(HALPREF)/stm32g0xx_ll_exti.c \
$(HALPREF)/stm32g0xx_ll_gpio.c \
$(HALPREF)/stm32g0xx_ll_i2c.c \
$(HALPREF)/stm32g0xx_ll_lptim.c \
$(HALPREF)/stm32g0xx_ll_lpuart.c \
$(HALPREF)/stm32g0xx_ll_pwr.c \
$(HALPREF)/stm32g0xx_ll_rcc.c \
$(HALPREF)/stm32g0xx_ll_rng.c \
$(HALPREF)/stm32g0xx_ll_rtc.c \
$(HALPREF)/stm32g0xx_ll_spi.c \
$(HALPREF)/stm32g0xx_ll_tim.c \
$(HALPREF)/stm32g0xx_ll_ucpd.c \
$(HALPREF)/stm32g0xx_ll_usart.c \
$(HALPREF)/stm32g0xx_ll_utils.c \
BMP ?= 1
LD_FLASH_SIZE ?= $(FLASH_SIZE)
# TODO move some of this to common stm32.mk
AS_SRC = $(STARTUP_FILE)
CPPFLAGS += \
-I$(PLATFORM)/stm32g0xx_hal_driver/Inc \
-I$(PLATFORM)/cmsis_device_g0/Include \
-I$(PLATFORM)/cmsis_core/Include
DEFINES += -DUSE_FULL_LL_DRIVER -DSTM32$(SERIES)
DEFINES += -D$(MCU) -DJD_FLASH_SIZE="1024*$(FLASH_SIZE)" -DFLASH_PAGE_SIZE=$(PAGE_SIZE) -DBL_SIZE="1024*$(BL_SIZE)"
include $(PLATFORM)/mk/$(MCU).mk
CONFIG_DEPS += $(wildcard $(PLATFORM)/mk/*.mk)
LD_SCRIPT = $(BUILT)/linker.ld
$(BUILT)/linker.ld: $(wildcard $(PLATFORM)/mk/*.mk) Makefile
mkdir -p $(BUILT)
: > $@
echo "MEMORY {" >> $@
echo "RAM (rwx) : ORIGIN = 0x20000000, LENGTH = $(RAM_SIZE)K" >> $@
ifeq ($(BL),)
# The -12 bytes is required by the flashing process, at least with BMP
echo "FLASH (rx) : ORIGIN = 0x8000000, LENGTH = $(LD_FLASH_SIZE)K - $(BL_SIZE)K - 12" >> $@
echo "}" >> $@
echo "INCLUDE $(JD_STM)/ld/gcc_arm.ld" >> $@
else
echo "FLASH (rx) : ORIGIN = 0x8000000 + $(LD_FLASH_SIZE)K - $(BL_SIZE)K, LENGTH = $(BL_SIZE)K" >> $@
echo "}" >> $@
echo "INCLUDE $(JD_STM)/ld/gcc_arm_bl_at_end.ld" >> $@
endif

Просмотреть файл

@ -7,6 +7,14 @@ struct TimDesc {
};
static const struct TimDesc tims[] = {
#ifdef STM32G0
#define APB1ENR APBENR1
#define APB2ENR APBENR2
{TIM1, 2, RCC_APBENR2_TIM1EN}, //
{TIM14, 2, RCC_APBENR2_TIM14EN}, //
{TIM16, 2, RCC_APBENR2_TIM16EN}, //
{TIM3, 1, RCC_APBENR1_TIM3EN}, //
#else
{TIM1, 2, RCC_APB2ENR_TIM1EN}, //
#ifdef TIM2
{TIM2, 1, RCC_APB1ENR_TIM2EN},
@ -14,7 +22,8 @@ static const struct TimDesc tims[] = {
{TIM3, 1, RCC_APB1ENR_TIM3EN}, //
{TIM14, 1, RCC_APB1ENR_TIM14EN}, //
{TIM16, 2, RCC_APB2ENR_TIM16EN}, //
// {TIM17, 2, RCC_APB2ENR_TIM17EN}, // used in tim.c, skip here
#endif
// TIM17 // used in tim.c, skip here
};
struct PinPWM {
@ -25,10 +34,16 @@ struct PinPWM {
};
static const struct PinPWM pins[] = {
#ifdef STM32G0
{PA_4, 1, LL_GPIO_AF_4, TIM14}, // PWM mikrobus
{PA_6, 1, LL_GPIO_AF_1, TIM3}, // rgb led
{PA_7, 2, LL_GPIO_AF_1, TIM3}, // rgb led
{PB_0, 3, LL_GPIO_AF_1, TIM3}, // rgb led
#else
#ifdef TIM2
{PA_1, 2, LL_GPIO_AF_2, TIM2}, // LED on jdm-v2
{PA_3, 4, LL_GPIO_AF_2, TIM2}, // POWER on jdm-v2
{PA_15, 1, LL_GPIO_AF_2, TIM2}, // LED on jdm-v3 (TIM2_CH1_ETR?)
{PA_1, 2, LL_GPIO_AF_2, TIM2}, // LED on jdm-v2
{PA_3, 4, LL_GPIO_AF_2, TIM2}, // POWER on jdm-v2
{PA_15, 1, LL_GPIO_AF_2, TIM2}, // LED on jdm-v3 (TIM2_CH1_ETR?)
#endif
//{PA_6, 1, LL_GPIO_AF_5, TIM16}, // SERVO on jdm-v2,3 - doesn't seem to work, TIM3 works
{PA_6, 1, LL_GPIO_AF_1, TIM3}, // SERVO on jdm-v2,3
@ -38,6 +53,7 @@ static const struct PinPWM pins[] = {
{PA_10, 3, LL_GPIO_AF_2, TIM1}, // SND
{PA_4, 1, LL_GPIO_AF_4, TIM14}, // SND
{PA_7, 1, LL_GPIO_AF_4, TIM14}, // servo
#endif
};
static const struct PinPWM *lookup_pwm(uint8_t pin) {
@ -63,7 +79,8 @@ uint8_t pwm_init(uint8_t pin, uint32_t period, uint32_t duty, uint8_t prescaler)
TIM_TypeDef *TIMx = pwm->tim;
if (prescaler == 0) prescaler = 1;
if (prescaler == 0)
prescaler = 1;
const struct TimDesc *td = lookup_tim(TIMx);
if (td->apb == 1) {

Просмотреть файл

@ -26,6 +26,15 @@ static ctx_t ctx_;
#define PIN_PWR_LOG -1
#endif
#ifdef STM32G0
#define RTC_IRQn RTC_TAMP_IRQn
#define RTC_IRQHandler RTC_TAMP_IRQHandler
#define EXTI_LINE LL_EXTI_LINE_19
#else
#define EXTI_LINE LL_EXTI_LINE_17
#define LL_EXTI_ClearRisingFlag_0_31 LL_EXTI_ClearFlag_0_31
#endif
#define BCD(t, h) (((t)&0xf) + 10 * (((t) >> 4) & ((1 << h) - 1)))
uint32_t rtc_get_seconds(void) {
uint32_t t = RTC->TR;
@ -111,7 +120,7 @@ static void rtc_set(ctx_t *ctx, uint32_t delta_us, cb_t f) {
LL_RTC_ALMA_SetSubSecond(RTC, nv);
LL_RTC_ClearFlag_ALRA(RTC);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_17);
LL_EXTI_ClearRisingFlag_0_31(EXTI_LINE);
NVIC_ClearPendingIRQ(RTC_IRQn);
LL_RTC_ALMA_Enable(RTC);
// pin_pulse(PIN_PWR_LOG, 1);
@ -137,11 +146,16 @@ void RTC_IRQHandler(void) {
}
// Clear the EXTI's Flag for RTC Alarm
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_17);
LL_EXTI_ClearRisingFlag_0_31(EXTI_LINE);
}
static void rtc_config(uint8_t p0, uint16_t p1) {
#ifdef STM32G0
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR | LL_APB1_GRP1_PERIPH_RTC);
#else
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
#endif
LL_PWR_EnableBkUpAccess();
LL_RCC_LSI_Enable();
@ -180,8 +194,8 @@ static void rtc_config(uint8_t p0, uint16_t p1) {
LL_RTC_ClearFlag_ALRA(RTC);
LL_RTC_EnableIT_ALRA(RTC);
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_17);
LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_17);
LL_EXTI_EnableIT_0_31(EXTI_LINE);
LL_EXTI_EnableRisingTrig_0_31(EXTI_LINE);
NVIC_SetPriority(RTC_IRQn, 2); // match tim.c
NVIC_EnableIRQ(RTC_IRQn);
@ -224,6 +238,7 @@ void rtc_init() {
rtc_sync_time();
}
// standby stuff not currently used
void rtc_set_to_seconds_and_standby() {
ctx_t *ctx = &ctx_;
@ -275,7 +290,11 @@ void rtc_sleep(bool forceShallow) {
}
rtc_set(&ctx_, usec, f);
#ifdef STM32G0
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);
#else
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_LPREGU);
#endif
// enable to test power in stand by; should be around 3.2uA
#if 0

Просмотреть файл

@ -30,4 +30,10 @@
#define HSI_MHZ 8
#define PLL_MHZ 48
// USART2 on lower end F0 can't be set to run from HSI
// we're not currently setup to handle clock freq switching at that time
#if USART_IDX != 1
#define DISABLE_PLL 1
#endif
#endif

Просмотреть файл

@ -17,7 +17,18 @@
#include "stm32g0xx_ll_tim.h"
#include "stm32g0xx_ll_spi.h"
#include "stm32g0xx_ll_adc.h"
#include "stm32g0xx_ll_rtc.h"
#include "stm32g0xx_ll_i2c.h"
#include "stm32g0xx_hal_rcc.h"
#define HSI_MHZ 16
#define PLL_MHZ 64
// USART2 on lower end G0 can't be set to run from HSI
// we're not currently setup to handle clock freq switching at that time
#if USART_IDX != 1
#define DISABLE_PLL 1
#endif
#endif

@ -0,0 +1 @@
Subproject commit 758febee2a1b4896b04792719f03c894c4164bac

Просмотреть файл

@ -124,10 +124,8 @@ static void DMA_Init(void) {
static void USART_UART_Init(void) {
#if USART_IDX == 2
#if defined(STM32F042x6)
// no usart clock source configuration required
#else
LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_HSI);
#ifndef DISABLE_PLL
#error "PLL not supported"
#endif
__HAL_RCC_USART2_CLK_ENABLE();
#elif USART_IDX == 1
@ -182,15 +180,14 @@ static void USART_UART_Init(void) {
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_5);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_5);
USARTx->CR1 = LL_USART_DATAWIDTH_8B | LL_USART_PARITY_NONE | LL_USART_OVERSAMPLING_8 |
LL_USART_DIRECTION_TX;
USARTx->BRR = HSI_MHZ * 2; // ->1MHz
#ifndef STM32F0
#error "maybe can use 16 oversampling if HSI_MHZ is 16"
#ifdef STM32G0
USARTx->CR1 = LL_USART_DATAWIDTH_8B | LL_USART_PARITY_NONE | LL_USART_OVERSAMPLING_16 |
LL_USART_DIRECTION_TX;
USARTx->BRR = HSI_MHZ; // ->1MHz
USARTx->BRR = HSI_MHZ; // ->1MHz (16x oversampling)
#else
USARTx->CR1 = LL_USART_DATAWIDTH_8B | LL_USART_PARITY_NONE | LL_USART_OVERSAMPLING_8 |
LL_USART_DIRECTION_TX;
USARTx->BRR = HSI_MHZ * 2; // ->1MHz (8x oversampling)
#endif
USARTx->CR2 = LL_USART_STOPBITS_1;
@ -201,9 +198,9 @@ static void USART_UART_Init(void) {
#endif
#ifdef LL_USART_FIFOTHRESHOLD_1_8
LL_USART_SetTXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
LL_USART_SetRXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
LL_USART_DisableFIFO(USARTx);
//LL_USART_SetTXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
//LL_USART_SetRXFIFOThreshold(USARTx, LL_USART_FIFOTHRESHOLD_1_8);
//LL_USART_DisableFIFO(USARTx);
#endif
LL_USART_ConfigHalfDuplexMode(USARTx);
LL_USART_EnableIT_ERROR(USARTx);
@ -282,17 +279,12 @@ int uart_start_tx(const void *data, uint32_t numbytes) {
LL_USART_EnableDMAReq_TX(USARTx);
// to here, it's about 1.3us
#ifndef STM32F0
#error "need time measurements for the wait_us below"
#endif
// the USART takes a few us to start transmiting
// this value gives 40us from the end of low pulse to start bit
#ifdef LOW_POWER
target_wait_us(24);
#else
target_wait_us(37);
#endif
// the USART takes a few us to start transmitting
target_wait_us(40);
// this works out to be:
// 57us on F0 at 8MHz
// 51us on G0 at 16MHz
// The spec requires min of 40us and max of 89us.
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);