rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Typedefs | Functions | Variables
stm32_common.cpp File Reference

Detailed Description

Low level common STM32 code.

Date
Mar 28, 2019
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file stm32_common.cpp.

Typedefs

typedef struct port_intctx intctx_t
 

Functions

static void reset_and_jump (void)
 
void jump_to_bootloader ()
 
void jump_to_openblt ()
 
BOR_Level_t BOR_Get (void)
 
BOR_Result_t BOR_Set (BOR_Level_t BORValue)
 
void startWatchdog (int timeoutMs)
 
void setWatchdogResetPeriod (int resetMs)
 
void tryResetWatchdog ()
 
uint32_t getMcuSerial ()
 
void baseMCUInit ()
 
int getRemainingStack (thread_t *otp)
 
bool isStm32F42x ()
 
PUBLIC_API_WEAK void boardPrepareForStop ()
 
void boardPreparePA0ForStandby ()
 
PUBLIC_API_WEAK void boardPrepareForStandby ()
 

Variables

static efitimems_t watchdogResetPeriodMs = 0
 
static const efitimems_t watchdogCounterResetDelay = 3000
 
uint32_t __main_stack_base__
 

Typedef Documentation

◆ intctx_t

typedef struct port_intctx intctx_t

Definition at line 213 of file stm32_common.cpp.

Function Documentation

◆ baseMCUInit()

void baseMCUInit ( )

Definition at line 195 of file stm32_common.cpp.

195 {
196 // looks like this holds a random value on start? Let's set a nice clean zero
197 DWT->CYCCNT = 0;
198
199
200#ifndef EFI_SKIP_BOR
201 BOR_Set(BOR_Level_1); // one step above default value
202#else
204#endif
205
206#ifndef EFI_BOOTLOADER
208#endif // EFI_BOOTLOADER
209}
TunerStudioOutputChannels outputChannels
Definition engine.h:109
@ BOR_Level_None
@ BOR_Level_1
static EngineAccessor engine
Definition engine.h:413
BOR_Result_t BOR_Set(BOR_Level_t BORValue)
uint32_t getMcuSerial()
Here is the call graph for this function:

◆ boardPrepareForStandby()

PUBLIC_API_WEAK void boardPrepareForStandby ( )

Definition at line 280 of file stm32_common.cpp.

280 {
282}
void boardPreparePA0ForStandby()

Referenced by stm32_standby().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ boardPrepareForStop()

PUBLIC_API_WEAK void boardPrepareForStop ( )

Definition at line 247 of file stm32_common.cpp.

247 {
248 // Default implementation - wake up on PA0 - boards should override this
249 palEnableLineEvent(PAL_LINE(GPIOA, 0), PAL_EVENT_MODE_RISING_EDGE);
250}

◆ boardPreparePA0ForStandby()

void boardPreparePA0ForStandby ( )

Standby uses special low power hardware - it always wakes on rising edge

Definition at line 256 of file stm32_common.cpp.

256 {
257#ifdef STM32F4XX
258 //Enable Wakeup Pin for PA0
259 PWR->CSR |= PWR_CSR_EWUP;
260
261 // Clear wakeup flag - it may be set if PA0 is already
262 // high when we enable it as a wake source
263 PWR->CR |= PWR_CR_CWUF; //Clear Wakeup Pin flag for PA0
264#endif
265
266#ifdef STM32F7XX
267 PWR->CSR2 |= PWR_CSR2_EWUP1; //EWUP1: Enable Wakeup pin for PA0
268 PWR->CR2 |= PWR_CR2_CWUPF1; //Clear Wakeup Pin flag for PA0
269#endif
270
271#ifdef STM32H7XX
272 // Wake on wakeup pin 0 - PA0
273 PWR->WKUPEPR = PWR_WKUPEPR_WKUPEN1;
274
275 // clear all possible wakeup bits
276 PWR->WKUPCR = 0xFFFFFFFF;
277#endif
278}

Referenced by boardPrepareForStandby().

Here is the caller graph for this function:

◆ BOR_Get()

BOR_Level_t BOR_Get ( void  )

Definition at line 86 of file stm32_common.cpp.

86 {
87 FLASH_OBProgramInitTypeDef FLASH_Handle;
88
89 /* Read option bytes */
90 HAL_FLASHEx_OBGetConfig(&FLASH_Handle);
91
92 /* Return BOR value */
93 return (BOR_Level_t) FLASH_Handle.BORLevel;
94}
BOR_Level_t
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
Get the Option byte configuration.
FLASH Option Bytes Program structure definition.

Referenced by BOR_Set().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ BOR_Set()

BOR_Result_t BOR_Set ( BOR_Level_t  BORValue)

Definition at line 96 of file stm32_common.cpp.

96 {
97 if (BOR_Get() == BORValue) {
98 return BOR_Result_Ok;
99 }
100
101
102 FLASH_OBProgramInitTypeDef FLASH_Handle;
103
104 FLASH_Handle.BORLevel = (uint32_t)BORValue;
105 FLASH_Handle.OptionType = OPTIONBYTE_BOR;
106
108
109 HAL_FLASHEx_OBProgram(&FLASH_Handle);
110
111 HAL_StatusTypeDef status = HAL_FLASH_OB_Launch();
112
114
115 if (status != HAL_OK) {
116 return BOR_Result_Error;
117 }
118
119 return BOR_Result_Ok;
120}
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
Launch the option byte loading.
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
Lock the FLASH Option Control Registers access.
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
Unlock the FLASH Option Control Registers access.
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
Program option bytes.
@ BOR_Result_Ok
Definition mpu_util.h:96
@ BOR_Result_Error
Definition mpu_util.h:97
BOR_Level_t BOR_Get(void)

Referenced by baseMCUInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMcuSerial()

uint32_t getMcuSerial ( )

Definition at line 190 of file stm32_common.cpp.

190 {
191 uint32_t *uid = ((uint32_t *)UID_BASE);
192 return uid[0] + uid[1] + uid[2];
193}

Referenced by baseMCUInit().

Here is the caller graph for this function:

◆ getRemainingStack()

int getRemainingStack ( thread_t *  otp)

Of note is that interrupts are NOT serviced on the stack of the thread that was running when the interrupt occurred. The only thing that happens on that thread's stack is that its registers are pushed (by hardware) when an interrupt occurs, just before swapping the stack pointer out for the main stack (currently 0x400=1024 bytes), where the ISR actually runs. see also main_stack_size see also process_stack_size

see also http://www.chibios.org/dokuwiki/doku.php?id=chibios:kb:stacks

In the firmware we are using 'extern *Engine' - in the firmware Engine is a singleton

On the other hand, in order to have a meaningful unit test we are passing Engine * engine as a parameter

Definition at line 215 of file stm32_common.cpp.

215 {
216#if CH_DBG_ENABLE_STACK_CHECK
217 // this would dismiss coverity warning - see http://rusefi.com/forum/viewtopic.php?f=5&t=655
218 // coverity[uninit_use]
219 register intctx_t *r13 asm ("r13");
220 otp->activeStack = r13;
221
222 int remainingStack;
223 if (ch0.dbg.isr_cnt > 0) {
224 // ISR context
225 remainingStack = (int)(r13 - 1) - (int)&__main_stack_base__;
226 } else {
227 remainingStack = (int)(r13 - 1) - (int)otp->wabase;
228 }
229 otp->remainingStack = remainingStack;
230 return remainingStack;
231#else
232 UNUSED(otp);
233 return 99999;
234#endif /* CH_DBG_ENABLE_STACK_CHECK */
235}
struct port_intctx intctx_t
UNUSED(samplingTimeSeconds)
uint32_t __main_stack_base__
Here is the call graph for this function:

◆ isStm32F42x()

bool isStm32F42x ( void  )

Definition at line 238 of file stm32_common.cpp.

238 {
239 // Device identifier
240 // 0x419 for STM32F42xxx and STM32F43xxx
241 // 0x413 for STM32F405xx/07xx and STM32F415xx/17xx
242 return ((DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID_Msk) == 0x419);
243}

◆ jump_to_bootloader()

void jump_to_bootloader ( )

Definition at line 63 of file stm32_common.cpp.

63 {
64 // leave DFU breadcrumb which assembly startup code would check, see [rusefi][DFU] section in assembly code
65
66 *((unsigned long *)0x2001FFF0) = 0xDEADBEEF; // End of RAM
67
69}
static void reset_and_jump(void)
Here is the call graph for this function:

◆ jump_to_openblt()

void jump_to_openblt ( )

Definition at line 72 of file stm32_common.cpp.

72 {
73#if EFI_USE_OPENBLT
74 /* safe to call on already inited shares area */
76 /* Store sing to stay in OpenBLT */
78
80#endif
81}
bool SharedParamsWriteByIndex(uint32_t idx, uint8_t value)
Writes a data byte to the shared parameter buffer at the specified index.
void SharedParamsInit(void)
Initializes the shared RAM parameters module.
Here is the call graph for this function:

◆ reset_and_jump()

static void reset_and_jump ( void  )
static

Definition at line 39 of file stm32_common.cpp.

39 {
40#if !ALLOW_JUMP_WITH_IGNITION_VOLTAGE
41 if (isIgnVoltage()) {
42 criticalError("Not allowed with ignition power");
43 return;
44 }
45#endif
46
47 #ifdef STM32H7XX
48 // H7 needs a forcible reset of the USB peripheral(s) in order for the bootloader to work properly.
49 // If you don't do this, the bootloader will execute, but USB doesn't work (nobody knows why)
50 // See https://community.st.com/s/question/0D53W00000vQEWsSAO/stm32h743-dfu-entry-doesnt-work-unless-boot0-held-high-at-poweron
51 #ifdef STM32H723xx
52 RCC->AHB1ENR &= ~(RCC_AHB1ENR_USB1OTGHSEN);
53 #else
54 RCC->AHB1ENR &= ~(RCC_AHB1ENR_USB1OTGHSEN | RCC_AHB1ENR_USB2OTGFSEN);
55 #endif
56 #endif
57
58 // and now reboot
59 NVIC_SystemReset();
60}
bool isIgnVoltage()

Referenced by jump_to_bootloader(), and jump_to_openblt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setWatchdogResetPeriod()

void setWatchdogResetPeriod ( int  resetMs)

Definition at line 160 of file stm32_common.cpp.

160 {
161#if 0
162 efiPrintf("[dev] wd %d", resetMs);
163#endif
165}
uint32_t efitimems_t
static efitimems_t watchdogResetPeriodMs

◆ startWatchdog()

void startWatchdog ( int  timeoutMs)

Definition at line 122 of file stm32_common.cpp.

122 {
123#if HAL_USE_WDG
124 // RL is a 12-bit value so we use a "2 ms" prescaler to support long timeouts (> 4.095 sec)
125 static WDGConfig wdgcfg;
126 wdgcfg.pr = STM32_IWDG_PR_64; // t = (1/32768) * 64 = ~2 ms
127 wdgcfg.rlr = STM32_IWDG_RL((uint32_t)((32.768f / 64.0f) * timeoutMs));
128#if STM32_IWDG_IS_WINDOWED
129 wdgcfg.winr = 0xfff; // don't use window
130#endif
131
132#ifndef __OPTIMIZE__ // gcc-specific built-in define
133 // if no optimizations, then it's most likely a debug version,
134 // and we need to enable a special watchdog feature to allow debugging
135 efiPrintf("Enabling 'debug freeze' watchdog feature...");
136#ifdef STM32H7XX
137 DBGMCU->APB4FZ1 |= DBGMCU_APB4FZ1_DBG_IWDG1;
138#else // F4 & F7
139 DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_IWDG_STOP;
140#endif // STM32H7XX
141#endif // __OPTIMIZE__
142
143 static bool isStarted = false;
144 if (!isStarted) {
145 efiPrintf("Starting watchdog with timeout %d ms...", timeoutMs);
146 wdgStart(&WDGD1, &wdgcfg);
147 isStarted = true;
148 } else {
149 efiPrintf("Changing watchdog timeout to %d ms...", timeoutMs);
150 // wdgStart() uses kernel lock, thus we cannot call it here from locked or ISR code
151 wdg_lld_start(&WDGD1);
152 }
153#endif // HAL_USE_WDG
154}

◆ tryResetWatchdog()

void tryResetWatchdog ( )

Definition at line 167 of file stm32_common.cpp.

167 {
168#if HAL_USE_WDG
169 static Timer lastTimeWasReset;
170 static efitimems_t wdUptime = 0;
171 // check if it's time to reset the watchdog
172 if (lastTimeWasReset.hasElapsedMs(watchdogResetPeriodMs)) {
173 // we assume tryResetWatchdog() is called from a timer callback
174 wdgResetI(&WDGD1);
175 lastTimeWasReset.reset();
176 // with 100 ms WD
177 if (wdUptime < watchdogCounterResetDelay) {
178 wdUptime += watchdogResetPeriodMs;
179 // we just crossed the treshold
180 if (wdUptime >= watchdogCounterResetDelay) {
181#if EFI_USE_OPENBLT
183#endif
184 }
185 }
186 }
187#endif // HAL_USE_WDG
188}
static const efitimems_t watchdogCounterResetDelay
Here is the call graph for this function:

Variable Documentation

◆ __main_stack_base__

uint32_t __main_stack_base__
extern

Referenced by getRemainingStack().

◆ watchdogCounterResetDelay

const efitimems_t watchdogCounterResetDelay = 3000
static

Definition at line 158 of file stm32_common.cpp.

Referenced by tryResetWatchdog().

◆ watchdogResetPeriodMs

efitimems_t watchdogResetPeriodMs = 0
static

Definition at line 156 of file stm32_common.cpp.

Referenced by setWatchdogResetPeriod(), and tryResetWatchdog().

Go to the source code of this file.