sl-firmware 4beef8da03 feat(firmware): OTA DFU entry via JLink command and Python flash script (Issue #124)
- Add ota.h / ota.c: ota_enter_dfu() (armed guard, writes BKP15R, resets),
  ota_fw_crc32() using STM32F7 hardware CRC peripheral (CRC-32/MPEG-2, 512 KB)
- Add JLINK_CMD_DFU_ENTER (0x06) and dfu_req flag to jlink.h / jlink.c
- Handle dfu_req in main loop: calls ota_enter_dfu(is_armed) — no-op if armed
- Update usbd_cdc_if.c: move DFU magic from BKP0R to BKP15R (OTA_DFU_BKP_IDX)
  resolving BKP register conflict with BNO055 calibration (BKP0R–6R, PR #150)
- Add scripts/flash_firmware.py: CRC-32/MPEG-2 + ISO-HDLC verification,
  dfu-util flash, host-side backup/rollback, --trigger-dfu JLink serial path
- Add test/test_ota.py: 42 tests passing (CRC-32/MPEG-2, CRC-16/XMODEM,
  DFU_ENTER frame structure, BKP register safety, flash constants)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 09:56:18 -05:00

58 lines
1.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ota.h"
#include "stm32f7xx_hal.h"
/* ---- ota_enter_dfu() ---- */
bool ota_enter_dfu(bool is_armed)
{
if (is_armed) return false;
/* Enable backup domain access */
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_RTC_ENABLE();
/*
* Write DFU magic to BKP15R.
* checkForBootloader() runs on next boot and jumps to the ST system
* bootloader at 0x1FF00000 when it finds this magic in BKP15R.
* BKP15R avoids the BNO055 calibration range (BKP0RBKP6R).
*
* RTC->BKP0R through BKP31R are laid out consecutively in memory,
* so (&RTC->BKP0R)[OTA_DFU_BKP_IDX] reaches BKP15R.
*/
(&RTC->BKP0R)[OTA_DFU_BKP_IDX] = OTA_DFU_MAGIC;
__disable_irq();
NVIC_SystemReset();
return true; /* never reached */
}
/* ---- ota_fw_crc32() ---- */
uint32_t ota_fw_crc32(void)
{
/*
* STM32F7 hardware CRC unit:
* Polynomial : 0x04C11DB7 (CRC-32/MPEG-2)
* Initial : 0xFFFFFFFF (CRC_INIT register default)
* Width : 32 bits
* Reflection : none
*
* The unit processes one 32-bit word at a time. Feeding the full
* 512 KB flash (128 K words) takes ~0.5 ms at 216 MHz.
*/
__HAL_RCC_CRC_CLK_ENABLE();
/* Reset CRC state; keep default 32-bit polynomial and no reversal */
CRC->CR = CRC_CR_RESET;
const uint32_t *p = (const uint32_t *)OTA_FLASH_BASE;
uint32_t words = OTA_FLASH_SIZE / 4u;
while (words--) {
CRC->DR = *p++;
}
return CRC->DR;
}