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 203 of file stm32_common.cpp.

Function Documentation

◆ baseMCUInit()

void baseMCUInit ( )

Definition at line 191 of file stm32_common.cpp.

191 {
192 // looks like this holds a random value on start? Let's set a nice clean zero
193 DWT->CYCCNT = 0;
194
195 BOR_Set(BOR_Level_1); // one step above default value
196#ifndef EFI_BOOTLOADER
198#endif // EFI_BOOTLOADER
199}
TunerStudioOutputChannels outputChannels
Definition engine.h:109
@ 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 270 of file stm32_common.cpp.

270 {
272}
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 237 of file stm32_common.cpp.

237 {
238 // Default implementation - wake up on PA0 - boards should override this
239 palEnableLineEvent(PAL_LINE(GPIOA, 0), PAL_EVENT_MODE_RISING_EDGE);
240}

◆ boardPreparePA0ForStandby()

void boardPreparePA0ForStandby ( )

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

Definition at line 246 of file stm32_common.cpp.

246 {
247#ifdef STM32F4XX
248 //Enable Wakeup Pin for PA0
249 PWR->CSR |= PWR_CSR_EWUP;
250
251 // Clear wakeup flag - it may be set if PA0 is already
252 // high when we enable it as a wake source
253 PWR->CR |= PWR_CR_CWUF; //Clear Wakeup Pin flag for PA0
254#endif
255
256#ifdef STM32F7XX
257 PWR->CSR2 |= PWR_CSR2_EWUP1; //EWUP1: Enable Wakeup pin for PA0
258 PWR->CR2 |= PWR_CR2_CWUPF1; //Clear Wakeup Pin flag for PA0
259#endif
260
261#ifdef STM32H7XX
262 // Wake on wakeup pin 0 - PA0
263 PWR->WKUPEPR = PWR_WKUPEPR_WKUPEN1;
264
265 // clear all possible wakeup bits
266 PWR->WKUPCR = 0xFFFFFFFF;
267#endif
268}

Referenced by boardPrepareForStandby().

Here is the caller graph for this function:

◆ BOR_Get()

BOR_Level_t BOR_Get ( void  )

Definition at line 82 of file stm32_common.cpp.

82 {
83 FLASH_OBProgramInitTypeDef FLASH_Handle;
84
85 /* Read option bytes */
86 HAL_FLASHEx_OBGetConfig(&FLASH_Handle);
87
88 /* Return BOR value */
89 return (BOR_Level_t) FLASH_Handle.BORLevel;
90}
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 92 of file stm32_common.cpp.

92 {
93 if (BOR_Get() == BORValue) {
94 return BOR_Result_Ok;
95 }
96
97
98 FLASH_OBProgramInitTypeDef FLASH_Handle;
99
100 FLASH_Handle.BORLevel = (uint32_t)BORValue;
101 FLASH_Handle.OptionType = OPTIONBYTE_BOR;
102
104
105 HAL_FLASHEx_OBProgram(&FLASH_Handle);
106
107 HAL_StatusTypeDef status = HAL_FLASH_OB_Launch();
108
110
111 if (status != HAL_OK) {
112 return BOR_Result_Error;
113 }
114
115 return BOR_Result_Ok;
116}
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 186 of file stm32_common.cpp.

186 {
187 uint32_t *uid = ((uint32_t *)UID_BASE);
188 return uid[0] + uid[1] + uid[2];
189}

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 205 of file stm32_common.cpp.

205 {
206#if CH_DBG_ENABLE_STACK_CHECK
207 // this would dismiss coverity warning - see http://rusefi.com/forum/viewtopic.php?f=5&t=655
208 // coverity[uninit_use]
209 register intctx_t *r13 asm ("r13");
210 otp->activeStack = r13;
211
212 int remainingStack;
213 if (ch0.dbg.isr_cnt > 0) {
214 // ISR context
215 remainingStack = (int)(r13 - 1) - (int)&__main_stack_base__;
216 } else {
217 remainingStack = (int)(r13 - 1) - (int)otp->wabase;
218 }
219 otp->remainingStack = remainingStack;
220 return remainingStack;
221#else
222 UNUSED(otp);
223 return 99999;
224#endif /* CH_DBG_ENABLE_STACK_CHECK */
225}
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 228 of file stm32_common.cpp.

228 {
229 // Device identifier
230 // 0x419 for STM32F42xxx and STM32F43xxx
231 // 0x413 for STM32F405xx/07xx and STM32F415xx/17xx
232 return ((DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID_Msk) == 0x419);
233}

◆ jump_to_bootloader()

void jump_to_bootloader ( )

Definition at line 59 of file stm32_common.cpp.

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

◆ jump_to_openblt()

void jump_to_openblt ( )

Definition at line 68 of file stm32_common.cpp.

68 {
69#if EFI_USE_OPENBLT
70 /* safe to call on already inited shares area */
72 /* Store sing to stay in OpenBLT */
74
76#endif
77}
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 RCC->AHB1ENR &= ~(RCC_AHB1ENR_USB1OTGHSEN | RCC_AHB1ENR_USB2OTGFSEN);
52 #endif
53
54 // and now reboot
55 NVIC_SystemReset();
56}
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 156 of file stm32_common.cpp.

156 {
157#if 0
158 efiPrintf("[dev] wd %d", resetMs);
159#endif
161}
uint32_t efitimems_t
static efitimems_t watchdogResetPeriodMs

◆ startWatchdog()

void startWatchdog ( int  timeoutMs)

Definition at line 118 of file stm32_common.cpp.

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

◆ tryResetWatchdog()

void tryResetWatchdog ( )

Definition at line 163 of file stm32_common.cpp.

163 {
164#if HAL_USE_WDG
165 static Timer lastTimeWasReset;
166 static efitimems_t wdUptime = 0;
167 // check if it's time to reset the watchdog
168 if (lastTimeWasReset.hasElapsedMs(watchdogResetPeriodMs)) {
169 // we assume tryResetWatchdog() is called from a timer callback
170 wdgResetI(&WDGD1);
171 lastTimeWasReset.reset();
172 // with 100 ms WD
173 if (wdUptime < watchdogCounterResetDelay) {
174 wdUptime += watchdogResetPeriodMs;
175 // we just crossed the treshold
176 if (wdUptime >= watchdogCounterResetDelay) {
177#if EFI_USE_OPENBLT
179#endif
180 }
181 }
182 }
183#endif // HAL_USE_WDG
184}
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 154 of file stm32_common.cpp.

Referenced by tryResetWatchdog().

◆ watchdogResetPeriodMs

efitimems_t watchdogResetPeriodMs = 0
static

Definition at line 152 of file stm32_common.cpp.

Referenced by setWatchdogResetPeriod(), and tryResetWatchdog().

Go to the source code of this file.