diff --git a/project/example/ble/ble_peripheral/app/src/PWM.h b/project/example/ble/ble_peripheral/app/src/PWM.h index 272ba68..6db13bd 100644 --- a/project/example/ble/ble_peripheral/app/src/PWM.h +++ b/project/example/ble/ble_peripheral/app/src/PWM.h @@ -147,6 +147,8 @@ void Bridge_Init(void); void Bridge_Off(void); void Bridge_Service_1ms(void); void Bridge_Deadtime_Expired(void); +uint8_t Bridge_PauseForFlash(void); +void Bridge_ResumeAfterFlash(uint8_t paused); #ifdef __cplusplus } #endif diff --git a/project/example/ble/ble_peripheral/app/src/bridge_pwm.c b/project/example/ble/ble_peripheral/app/src/bridge_pwm.c index 2faf280..0b3a82c 100644 --- a/project/example/ble/ble_peripheral/app/src/bridge_pwm.c +++ b/project/example/ble/ble_peripheral/app/src/bridge_pwm.c @@ -246,6 +246,28 @@ void Bridge_Off(void) output_mode = BRIDGE_MODE_OFF; } +uint8_t Bridge_PauseForFlash(void) +{ + /* + * Single-color output is hardware PWM and remains stable while flash + * masks interrupts. Dual-color output is Timer3-driven, so force both + * bridge inputs low before flash can stretch an active direction pulse. + */ + if (!bridge_ready || output_mode != BRIDGE_MODE_DUAL) { + return 0U; + } + + Bridge_Off(); + return 1U; +} + +void Bridge_ResumeAfterFlash(uint8_t paused) +{ + if (paused) { + Bridge_Service_1ms(); + } +} + __RAM_CODE void Bridge_Deadtime_Expired(void) { uint32_t w_step; diff --git a/project/example/ble/ble_peripheral/app/src/ota_flash_interface.c b/project/example/ble/ble_peripheral/app/src/ota_flash_interface.c index 84eeeff..2a7f87c 100644 --- a/project/example/ble/ble_peripheral/app/src/ota_flash_interface.c +++ b/project/example/ble/ble_peripheral/app/src/ota_flash_interface.c @@ -1,9 +1,11 @@ #include "ota_flash_interface.h" +#include "xc_drv_fmc_spi.h" #include "arch.h" #include "dbg.h" // extern uint8_t ble_flash_operation_can_check(void); #include "ota_protocol.h" #include "fmc_spi.h" +#include "pwm.h" op_flash_t op_flash = { OP_IDEL, }; @@ -97,10 +99,23 @@ uint8_t app_data[FLASH_PAGE_SIZE] = {0}; //uint16_t app_op_flash_start = 10000; void app_op_flash(void) { + uint8_t bridge_paused; if(op_flash.op_state == OP_IDEL&&app_op_flash_flag ==0) { - ble_flash_later_page_erase(0x1E000); + /* + * Commit user data as one transaction. Timer3 cannot advance + * dual-color PWM while flash masks interrupts, so hold the + * H-bridge at 00 and resume from a fresh complete frame. + * Hardware PWM single-color output does not need pausing. + */ + GLOBAL_INT_DISABLE(); + bridge_paused = Bridge_PauseForFlash(); + FMC_SPI_Flash_Erase_Page(0x1E000); + FMC_SPI_Flash_WritePage(0x1E000, app_data, FLASH_PAGE_SIZE); + GLOBAL_INT_RESTORE(); + app_op_flash_flag = 2; + Bridge_ResumeAfterFlash(bridge_paused); } else if(op_flash.op_state == OP_IDEL &&app_op_flash_flag ==1) {