Merge pull request 'fix(usb): MPU non-cacheable region + IWDG ordering fix (bd-3ulu)' (#10) from sl-firmware/bd-3ulu-usb-dcache-fix into main
This commit is contained in:
commit
257d6ccf26
@ -16,8 +16,21 @@ volatile uint8_t cdc_disarm_request = 0; /* set by D command */
|
||||
volatile uint8_t cdc_cmd_ready = 0;
|
||||
volatile char cdc_cmd_buf[32];
|
||||
|
||||
static uint8_t UserRxBuffer[256];
|
||||
static uint8_t UserTxBuffer[256];
|
||||
/*
|
||||
* USB TX/RX buffers grouped into a single 512-byte aligned struct so that
|
||||
* one MPU region (configured in usbd_conf.c) can mark them non-cacheable.
|
||||
* Size must be a power-of-2 >= total size for MPU RASR SIZE encoding.
|
||||
*/
|
||||
static struct {
|
||||
uint8_t tx[256];
|
||||
uint8_t rx[256];
|
||||
} __attribute__((aligned(512))) usb_nc_buf;
|
||||
|
||||
#define UserTxBuffer usb_nc_buf.tx
|
||||
#define UserRxBuffer usb_nc_buf.rx
|
||||
|
||||
/* Exported so usbd_conf.c USB_NC_MPU_Config() can set the region base */
|
||||
void * const usb_nc_buf_base = &usb_nc_buf;
|
||||
|
||||
/*
|
||||
* Betaflight-proven DFU reboot:
|
||||
|
||||
@ -5,6 +5,33 @@
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/*
|
||||
* Mark USB TX/RX buffers non-cacheable via MPU Region 0.
|
||||
* Cortex-M7 TEX=1, C=0, B=0 → Normal Non-cacheable.
|
||||
* Called before HAL_PCD_Init() so the region is active before the USB
|
||||
* hardware ever touches the buffers.
|
||||
*/
|
||||
extern void * const usb_nc_buf_base; /* defined in usbd_cdc_if.c */
|
||||
|
||||
static void USB_NC_MPU_Config(void)
|
||||
{
|
||||
MPU_Region_InitTypeDef r = {0};
|
||||
HAL_MPU_Disable();
|
||||
r.Enable = MPU_REGION_ENABLE;
|
||||
r.Number = MPU_REGION_NUMBER0;
|
||||
r.BaseAddress = (uint32_t)usb_nc_buf_base;
|
||||
r.Size = MPU_REGION_SIZE_512B;
|
||||
r.SubRegionDisable = 0x00;
|
||||
r.TypeExtField = MPU_TEX_LEVEL1; /* TEX=1 */
|
||||
r.AccessPermission = MPU_REGION_FULL_ACCESS;
|
||||
r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
|
||||
r.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* C=0 */
|
||||
r.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; /* B=0 */
|
||||
HAL_MPU_ConfigRegion(&r);
|
||||
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
|
||||
}
|
||||
|
||||
PCD_HandleTypeDef hpcd;
|
||||
|
||||
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
|
||||
@ -68,6 +95,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
|
||||
hpcd.pData = pdev;
|
||||
pdev->pData = &hpcd;
|
||||
|
||||
USB_NC_MPU_Config(); /* Mark USB buffers non-cacheable before USB hardware init */
|
||||
HAL_PCD_Init(&hpcd);
|
||||
|
||||
HAL_PCDEx_SetRxFiFo(&hpcd, 0x80);
|
||||
|
||||
19
src/crsf.c
Normal file
19
src/crsf.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* crsf.c — CRSF RC receiver stub (UART not yet wired on MAMBA F722S).
|
||||
* crsf_state.last_rx_ms stays 0 so safety_rc_alive() always returns false,
|
||||
* which keeps USB-only mode active (RC timeout disarm is commented out in main.c).
|
||||
*/
|
||||
#include "crsf.h"
|
||||
|
||||
volatile CRSFState crsf_state = {0};
|
||||
|
||||
void crsf_init(void) {}
|
||||
|
||||
void crsf_parse_byte(uint8_t byte) { (void)byte; }
|
||||
|
||||
int16_t crsf_to_range(uint16_t val, int16_t min, int16_t max)
|
||||
{
|
||||
/* CRSF range 172-1811 → linear map to [min, max] */
|
||||
int32_t v = (int32_t)val;
|
||||
return (int16_t)(min + (v - 172) * (max - min) / (1811 - 172));
|
||||
}
|
||||
18
src/main.c
18
src/main.c
@ -90,7 +90,7 @@ void SysTick_Handler(void) { HAL_IncTick(); }
|
||||
|
||||
int main(void) {
|
||||
SCB_EnableICache();
|
||||
SCB_DisableDCache(); /* Must be off before USB starts — STM32F7 DCache/USB coherency */
|
||||
/* DCache stays ON — MPU Region 0 in usbd_conf.c marks USB buffers non-cacheable. */
|
||||
checkForBootloader(); /* Check RTC magic BEFORE HAL_Init — must be first thing */
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
@ -104,14 +104,6 @@ int main(void) {
|
||||
status_init();
|
||||
HAL_Delay(3000); /* Wait for USB host to enumerate */
|
||||
|
||||
/*
|
||||
* IWDG starts after the USB enumeration delay — avoids spurious reset
|
||||
* during the 3s startup hold. Once started, safety_refresh() MUST be
|
||||
* called at least every WATCHDOG_TIMEOUT_MS (50ms) or MCU resets.
|
||||
* IWDG cannot be stopped once started (hardware enforced).
|
||||
*/
|
||||
safety_init();
|
||||
|
||||
/* Init IMU (MPU6000 via SPI1 — mpu6000.c wraps icm42688 + complementary filter) */
|
||||
int imu_ret = mpu6000_init() ? 0 : -1;
|
||||
|
||||
@ -122,6 +114,14 @@ int main(void) {
|
||||
balance_t bal;
|
||||
balance_init(&bal);
|
||||
|
||||
/*
|
||||
* IWDG starts AFTER all peripheral inits — avoids reset during mpu6000_init()
|
||||
* which takes ~510ms (well above the 50ms WATCHDOG_TIMEOUT_MS).
|
||||
* Once started, safety_refresh() MUST be called every WATCHDOG_TIMEOUT_MS
|
||||
* or MCU resets. IWDG cannot be stopped once started (hardware enforced).
|
||||
*/
|
||||
safety_init();
|
||||
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
|
||||
@ -16,8 +16,9 @@
|
||||
|
||||
/* IWDG prescaler 32 → LSI(40kHz)/32 = 1250 ticks/sec → 0.8ms/tick */
|
||||
#define IWDG_PRESCALER IWDG_PRESCALER_32
|
||||
#define IWDG_TICK_MS (32.0f / 40.0f) /* 0.8ms per tick */
|
||||
#define IWDG_RELOAD ((uint32_t)(WATCHDOG_TIMEOUT_MS / IWDG_TICK_MS))
|
||||
/* Integer formula: timeout_ms * LSI_HZ / (prescaler * 1000)
|
||||
* = WATCHDOG_TIMEOUT_MS * 40000 / (32 * 1000) = WATCHDOG_TIMEOUT_MS * 40 / 32 */
|
||||
#define IWDG_RELOAD (WATCHDOG_TIMEOUT_MS * 40UL / 32UL)
|
||||
|
||||
#if IWDG_RELOAD > 4095
|
||||
# error "WATCHDOG_TIMEOUT_MS too large for IWDG_PRESCALER_32 — increase prescaler"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user