Author Archives: te-bachi

STM32 Flash Option Bytes Programming


Utilities

dfu-util – Device Firmware Upgrade Utilities


Forum

ST

How to program FLASH_OPTR register to survive system reset?
Programming STM32 in bootloader mode under Linux
Unlock readout protection
STM32F0 read out protection problem

Mikrocontroller.net

STM32 Option Bytes beim Flashen gleich mit verändern


Register Access

STM32F3 Anleitung (ohne HAL, SET_BIT, etc.)

Schauen wir uns den modify Befehl genauer an:

MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER5, GPIO_MODER_MODER5_0);

Dies bedeutet: Modifiziere im Register GPIOA->MODER das Feld MODER5. Schalte dort nur das
untere Bit 0 an. Alle anderen Felder bleiben unverändert.
Falls du schon mit bitweisen Operationen vertraut bist, kannst du stattdessen auch schreiben:

GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODER5) | GPIO_MODER_MODER5_0;
  • RM0440: STM32G4 Reference manual
  • ST production value: 0xFFEF F8AA

Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g4xx.h

  • SET_BIT
  • CLEAR_BIT
  • READ_BIT
  • CLEAR_REG
  • MODIFY_REG
  • WRITE_REG
  • READ_reg


FLASH Register: Option Bytes

typedef struct
{
  __IO uint32_t ACR;              /*!< FLASH access control register,            Address offset: 0x00 */
  __IO uint32_t PDKEYR;           /*!< FLASH power down key register,            Address offset: 0x04 */
  __IO uint32_t KEYR;             /*!< FLASH key register,                       Address offset: 0x08 */
  __IO uint32_t OPTKEYR;          /*!< FLASH option key register,                Address offset: 0x0C */
  __IO uint32_t SR;               /*!< FLASH status register,                    Address offset: 0x10 */
  __IO uint32_t CR;               /*!< FLASH control register,                   Address offset: 0x14 */
  __IO uint32_t ECCR;             /*!< FLASH ECC register,                       Address offset: 0x18 */
       uint32_t RESERVED1;        /*!< Reserved1,                                Address offset: 0x1C */
  __IO uint32_t OPTR;             /*!< FLASH option register,                    Address offset: 0x20 */
  __IO uint32_t PCROP1SR;         /*!< FLASH bank1 PCROP start address register, Address offset: 0x24 */
  __IO uint32_t PCROP1ER;         /*!< FLASH bank1 PCROP end address register,   Address offset: 0x28 */
  __IO uint32_t WRP1AR;           /*!< FLASH bank1 WRP area A address register,  Address offset: 0x2C */
  __IO uint32_t WRP1BR;           /*!< FLASH bank1 WRP area B address register,  Address offset: 0x30 */
       uint32_t RESERVED2[4];     /*!< Reserved2,                                Address offset: 0x34 */
  __IO uint32_t PCROP2SR;         /*!< FLASH bank2 PCROP start address register, Address offset: 0x44 */
  __IO uint32_t PCROP2ER;         /*!< FLASH bank2 PCROP end address register,   Address offset: 0x48 */
  __IO uint32_t WRP2AR;           /*!< FLASH bank2 WRP area A address register,  Address offset: 0x4C */
  __IO uint32_t WRP2BR;           /*!< FLASH bank2 WRP area B address register,  Address offset: 0x50 */
       uint32_t RESERVED3[7];     /*!< Reserved3,                                Address offset: 0x54 */
  __IO uint32_t SEC1R;            /*!< FLASH Securable memory register bank1,    Address offset: 0x70 */
  __IO uint32_t SEC2R;            /*!< FLASH Securable memory register bank2,    Address offset: 0x74 */
} FLASH_TypeDef;
printf("FLASH->OPTR = %" PRIx32 "\n", FLASH->OPTR);
printf("  RDP         = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP_Msk)         >> FLASH_OPTR_RDP_Pos);
printf("  BOR_LEV     = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_BOR_LEV_Msk)     >> FLASH_OPTR_BOR_LEV_Pos);
printf("  nRST_STOP   = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nRST_STOP_Msk)   >> FLASH_OPTR_nRST_STOP_Pos);
printf("  nRST_STDBY  = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nRST_STDBY_Msk)  >> FLASH_OPTR_nRST_STDBY_Pos);
printf("  nRST_SHDW   = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nRST_SHDW_Msk)   >> FLASH_OPTR_nRST_SHDW_Pos);
printf("  IWDG_SW     = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_IWDG_SW_Msk)     >> FLASH_OPTR_IWDG_SW_Pos);
printf("  IWDG_STOP   = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_IWDG_STOP_Msk)   >> FLASH_OPTR_IWDG_STOP_Pos);
printf("  IWDG_STDBY  = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_IWDG_STDBY_Msk)  >> FLASH_OPTR_IWDG_STDBY_Pos);
printf("  WWDG_SW     = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_WWDG_SW_Msk)     >> FLASH_OPTR_WWDG_SW_Pos);
printf("  BFB2        = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_BFB2_Msk)        >> FLASH_OPTR_BFB2_Pos);
printf("  DBANK       = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK_Msk)       >> FLASH_OPTR_DBANK_Pos);
printf("  nBOOT1      = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT1_Msk)      >> FLASH_OPTR_nBOOT1_Pos);
printf("  SRAM_PE     = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_SRAM_PE_Msk)     >> FLASH_OPTR_SRAM_PE_Pos);
printf("  CCMSRAM_RST = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_CCMSRAM_RST_Msk) >> FLASH_OPTR_CCMSRAM_RST_Pos);
printf("  nSWBOOT0    = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nSWBOOT0_Msk)    >> FLASH_OPTR_nSWBOOT0_Pos);
printf("  nBOOT0      = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_nBOOT0_Msk)      >> FLASH_OPTR_nBOOT0_Pos);
printf("  NRST_MODE   = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE_Msk)   >> FLASH_OPTR_NRST_MODE_Pos);
printf("  IRHEN       = %" PRIx32 "\n", READ_BIT(FLASH->OPTR, FLASH_OPTR_IRHEN_Msk)       >> FLASH_OPTR_IRHEN_Pos);
FLASH->OPTR = fbeff8aa
  RDP         = aa
  BOR_LEV     = 0
  nRST_STOP   = 1
  nRST_STDBY  = 1
  nRST_SHDW   = 1
  IWDG_SW     = 1
  IWDG_STOP   = 1
  IWDG_STDBY  = 1
  WWDG_SW     = 1
  BFB2        = 0
  DBANK       = 1
  nBOOT1      = 1
  SRAM_PE     = 1
  CCMSRAM_RST = 1
  nSWBOOT0    = 0
  nBOOT0      = 1
  NRST_MODE   = 3
  IRHEN       = 1
HAL_FLASHEx_OBGetConfig(&FLASH_OBInitStruct);

/* Get BOR Option Bytes */
if((FLASH_OBInitStruct.BORLevel & 0x0C) != BOR_LEVEL) 
{
  /* Unlock the option bytes block access */
  HAL_FLASH_OB_Unlock();
  
  /* Select the desired V(BOR) Level */
  FLASH_OBInitStruct.OptionType = OPTIONBYTE_BOR;
  FLASH_OBInitStruct.BORLevel = BOR_LEVEL;
  HAL_FLASHEx_OBProgram(&FLASH_OBInitStruct);
  
  /* Launch the option byte loading */
  HAL_FLASH_OB_Launch();
  
  /* Locks the option bytes block access */
  HAL_FLASH_OB_Lock();
}
/* Program operation functions  ***********************************************/
HAL_StatusTypeDef  HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
HAL_StatusTypeDef  HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data);

/* FLASH IRQ handler method */
void               HAL_FLASH_IRQHandler(void);

/* Callbacks in non blocking modes */
void               HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
void               HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue);


/* Peripheral Control functions  **********************************************/
HAL_StatusTypeDef  HAL_FLASH_Unlock(void);
HAL_StatusTypeDef  HAL_FLASH_Lock(void);

/* Option bytes control */
HAL_StatusTypeDef  HAL_FLASH_OB_Unlock(void);
HAL_StatusTypeDef  HAL_FLASH_OB_Lock(void);
HAL_StatusTypeDef  HAL_FLASH_OB_Launch(void);
/* Extended Program operation functions  *************************************/
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
void              HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
HAL_StatusTypeDef HAL_FLASHEx_EnableSecMemProtection(uint32_t Bank);
void              HAL_FLASHEx_EnableDebugger(void);
void              HAL_FLASHEx_DisableDebugger(void);
/* Private function prototypes -----------------------------------------------*/
static void              FLASH_MassErase(uint32_t Banks);
static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);
static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);
static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
static uint32_t          FLASH_OB_GetRDP(void);
static uint32_t          FLASH_OB_GetUser(void);
static void              FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr);
static HAL_StatusTypeDef FLASH_OB_SecMemConfig(uint32_t SecMemBank, uint32_t SecMemSize);
static void              FLASH_OB_GetSecMem(uint32_t SecMemBank, uint32_t *SecMemSize);
static HAL_StatusTypeDef FLASH_OB_BootLockConfig(uint32_t BootLockConfig);
static uint32_t          FLASH_OB_GetBootLock(void);
/** @defgroup FLASH_OB_Type FLASH Option Bytes Type */
#define OPTIONBYTE_WRP            0x01U                    /*!< WRP option byte configuration */
#define OPTIONBYTE_RDP            0x02U                    /*!< RDP option byte configuration */
#define OPTIONBYTE_USER           0x04U                    /*!< USER option byte configuration */
#define OPTIONBYTE_PCROP          0x08U                    /*!< PCROP option byte configuration */
#define OPTIONBYTE_BOOT_LOCK      0x10U                    /*!< Boot lock option byte configuration */
#define OPTIONBYTE_SEC            0x20U                    /*!< Securable memory option byte configuration */

#define OB_USER_BOR_LEV           0x00000001U              /*!< BOR reset Level */
#define OB_USER_nRST_STOP         0x00000002U              /*!< Reset generated when entering the stop mode */
#define OB_USER_nRST_STDBY        0x00000004U              /*!< Reset generated when entering the standby mode */
#define OB_USER_IWDG_SW           0x00000008U              /*!< Independent watchdog selection */
#define OB_USER_IWDG_STOP         0x00000010U              /*!< Independent watchdog counter freeze in stop mode */
#define OB_USER_IWDG_STDBY        0x00000020U              /*!< Independent watchdog counter freeze in standby mode */
#define OB_USER_WWDG_SW           0x00000040U              /*!< Window watchdog selection */
#define OB_USER_BFB2              0x00000080U              /*!< Dual-bank boot */
#define OB_USER_DBANK             0x00000100U              /*!< Single bank with 128-bits data or two banks with 64-bits data */
#define OB_USER_nBOOT1            0x00000200U              /*!< Boot configuration */
#define OB_USER_SRAM_PE           0x00000400U              /*!< SRAM parity check enable (first 32kB of SRAM1 + CCM SRAM) */
#define OB_USER_CCMSRAM_RST       0x00000800U              /*!< CCMSRAM Erase when system reset */
#define OB_USER_nRST_SHDW         0x00001000U              /*!< Reset generated when entering the shutdown mode */
#define OB_USER_nSWBOOT0          0x00002000U              /*!< Software BOOT0 */
#define OB_USER_nBOOT0            0x00004000U              /*!< nBOOT0 option bit */
#define OB_USER_NRST_MODE         0x00008000U              /*!< Reset pin configuration */
#define OB_USER_IRHEN             0x00010000U              /*!< Internal Reset Holder enable */

/**
  * @brief  FLASH Option Bytes Program structure definition
  */
typedef struct
{
  uint32_t OptionType;     /*!< Option byte to be configured. */
  [...]
  uint32_t USERType;       /*!< User option byte(s) to be configured (used for OPTIONBYTE_USER). */
  uint32_t USERConfig;     /*!< Value of the user option byte (used for OPTIONBYTE_USER). */
  [...]
} FLASH_OBProgramInitTypeDef;
/* Load */
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
{
  pOBInit->OptionType = (OPTIONBYTE_RDP | OPTIONBYTE_USER);

  [...]

  /* Get Read protection level */
  pOBInit->RDPLevel = FLASH_OB_GetRDP();

  /* Get the user option bytes */
  pOBInit->USERConfig = FLASH_OB_GetUser();

  [...]

  pOBInit->OptionType |= OPTIONBYTE_BOOT_LOCK;

  /* Get the boot entry point */
  pOBInit->BootEntryPoint = FLASH_OB_GetBootLock();

  [...]
}

/* Save */
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
{
  [...]

  /* User Configuration */
  if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
  {
    /* Configure the user option bytes */
    if (FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig) != HAL_OK)
    {
      status = HAL_ERROR;
    }
  }

  [...]
}

/* Private */
static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
{
    [...]

    if ((UserType & OB_USER_nBOOT0) != 0U)
    {
      /* nBOOT0 option byte should be modified */
      assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));

      /* Set value and mask for nBOOT0 option byte */
      optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);
      optr_reg_mask |= FLASH_OPTR_nBOOT0;
    }

    [...]

    /* Configure the option bytes register */
    MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);

    /* Set OPTSTRT Bit */
    SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  }

  return status;
}

Linux: Lenovo ThinkPad P15s Gen2

Fn-Taste

So tauschen Sie die Tastaturtasten Fn (Funktion) und Strg (Steuerung) im BIOS

  1. Starte den Computer neu.
  2. Rufen Sie das System- BIOS.
  3. Gehen Sie zu Config -> Tastatur / Maus -> Fn und Ctrl Key Swap.

Verwendung der Funktionstasten ohne Drücken von Fn

  • Drücken Sie Fn + Esc , um die Fn-Sperre zu aktivieren und die Hotkey-Funktion zu deaktivieren.
  1. Greifen Sie auf das BIOS.
  2. Wählen Sie im BIOS Menü die Registerkarte Konfiguration.
  3. Wählen Sie den Hotkey-Modus und setzen Sie ihn auf Deaktiviert.
  4. Speichern und beenden Sie das BIOS Menü (drücken Sie F10 und dann die Eingabetaste).

nvidia Quadro T500

LINUX X64 (AMD64/EM64T) DISPLAY DRIVER 470.63.01
LINUX X64 (AMD64/EM64T) DISPLAY DRIVER 470.57.02
nouveau stalled at ffff error message while trying to convert Windows 10 laptop to Ubuntu

#doesn't work
nouveau.modeset=0

# works!
modprobe.blacklist=nouveau
root        1596  0.7  0.4 402856 80208 ?        Ssl  21:38   0:05 /usr/lib/packagekit/packagekitd
root        2918  0.9  0.3 404580 49724 pts/1    Ss+  21:45   0:02  \_ /usr/lib/packagekit/packagekitd
root        4041  0.0  0.0  17596  9064 pts/2    Ss+  21:47   0:00      \_ /usr/bin/dpkg --status-fd 75 --configure --pending
root        4192  0.0  0.0   2608  1632 pts/2    S+   21:47   0:00          \_ /bin/sh /var/lib/dpkg/info/nvidia-dkms-470.postinst configure
root        4204 14.2  0.2  45296 33440 pts/2    S+   21:47   0:29              \_ /usr/bin/perl -w /usr/share/debconf/frontend /usr/lib/dkms/common.postinst nvidia 470.57.02 /usr/share/nvidia x86_64
root        4222  0.0  0.0   2608  1920 pts/2    S+   21:47   0:00                  \_ /bin/sh /usr/lib/dkms/common.postinst nvidia 470.57.02 /usr/share/nvidia x86_64
root        4337  0.0  0.0  11756  5436 pts/2    S+   21:47   0:00                      \_ /bin/bash /usr/sbin/dkms build -m nvidia -v 470.57.02 -k 5.4.0-74-generic -a x86_64
root        4343  0.0  0.0  12272  4688 pts/2    S+   21:47   0:00                          \_ /bin/bash /usr/sbin/dkms build -m nvidia -v 470.57.02 -k 5.4.0-74-generic -a x86_64
root       11649 13.8  0.0   2608  1680 pts/2    S+   21:49   0:08                              \_ /bin/sh /sbin/update-secureboot-policy --enroll-key

root       18554  0.3  0.4  83256 69600 pts/1    S+   09:09   0:00      |       \_ apt-get install
root       18565  0.0  0.0  17464  8888 pts/2    Ss+  09:09   0:00      |           \_ /usr/bin/dpkg --status-fd 65 --configure --pending
root       18566  0.0  0.0   2608  1652 pts/2    S+   09:09   0:00      |               \_ /bin/sh /var/lib/dpkg/info/nvidia-dkms-470.postinst configure
root       18578  0.0  0.1  36360 24540 pts/2    S+   09:09   0:00      |                   \_ /usr/bin/perl -w /usr/share/debconf/frontend /usr/lib/dkms/common.postinst nvidia 470.57.02 /usr/share/nvidia x86_64
root       18584  0.0  0.0   2608  1800 pts/2    S+   09:09   0:00      |                       \_ /bin/sh /usr/lib/dkms/common.postinst nvidia 470.57.02 /usr/share/nvidia x86_64
root       18726  0.0  0.0  11676  5448 pts/2    S+   09:09   0:00      |                       |   \_ /bin/bash /usr/sbin/dkms build -m nvidia -v 470.57.02 -k 5.4.0-74-generic -a x86_64
root       18732  0.0  0.0  12324  4732 pts/2    S+   09:09   0:00      |                       |       \_ /bin/bash /usr/sbin/dkms build -m nvidia -v 470.57.02 -k 5.4.0-74-generic -a x86_64
root       25962  0.0  0.0   2608  1696 pts/2    S+   09:10   0:00      |                       |           \_ /bin/sh /sbin/update-secureboot-policy --enroll-key
root       26013  0.0  0.0  14016  5060 pts/2    S+   09:11   0:00      |                       \_ whiptail --backtitle Package configuration --title Configuring Secure Boot --output-fd 12 --nocancel --msgbox Your system has UEFI Secure B

Your system has UEFI Secure Boot enabled.
UEFI Secure Boot requires additional configuration to work with third-party drivers.
The system will assist you in configuring UEFI Secure Boot. To permit the use of third-party drivers, a new Machine-Owner Key (MOK) has been generated. This key now needs to be enrolled in your system’s firmware.
To ensure that this change is being made by you as an authorized user, and not by an attacker, you must choose a password now and then confirm the change after reboot using the same password, in both the “Enroll MOK” and “Change
Secure Boot state” menus that will be presented to you when this system reboots.
If you proceed but do not confirm the password upon reboot, Ubuntu will still be able to boot on your system but any hardware that requires third-party drivers to work correctly may not be usable.

STM32 OPAMP + ADC

Shared Pins for OPAMP + ADC

config OPAMP in non-inverting configuration with the output of opamp connected to ADC: is it possible?

Internal Output Routing OPAMP + ADC

  • Register: OPAINTOEN

Internal Output Routing DAC + OPAMP

OPAMP fail to calibrate

[SILICON BUG ?] Why does OPAMP fail to calibrate with internal output routing? (STM32G474)

Routing external or internal?

STM32G opamps routing to ADC and to comparator

General Information

STM32L4 training: 04.6 Analog peripherals – Hands-on OPAMP

STM32L4 training: 04.6 Analog peripherals – Hands-on OPAMP

STM32G4 OLT – 24 . Analog ADC

  • in block diagram the Input MUX has no connection to OPAMP!

STM32G4 OLT – 27 . Analog OPAMP

  • no info how to configure OPAMP to route to ADC!

STM32G4 OLT – 27 . Analog OPAMP

ADC from OPAMP Output

AN2834: How to get the best ADC accuracy in STM32 microcontrollers

AN2834: How to get the best ADC accuracy in STM32 microcontrollers

AN5306: Operational Amplifier (OPAMP) usage in STM32G4 Series

AN5306: Operational Amplifier (OPAMP) usage in STM32G4 Series