support for STM32G0 series (#16)
* 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:
Родитель
48be0d64ef
Коммит
86de72c8dc
|
@ -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
|
||||
|
|
26
bl/blmain.c
26
bl/blmain.c
|
@ -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)
|
||||
|
|
13
bl/bluart.c
13
bl/bluart.c
|
@ -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
|
24
stm32/adc.c
24
stm32/adc.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
25
stm32/i2c.c
25
stm32/i2c.c
|
@ -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
|
||||
|
|
35
stm32/init.c
35
stm32/init.c
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
27
stm32/pwm.c
27
stm32/pwm.c
|
@ -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) {
|
||||
|
|
27
stm32/rtc.c
27
stm32/rtc.c
|
@ -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
|
42
stm32/uart.c
42
stm32/uart.c
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче