#include "rs485_boot_stm32g474vet.h" #include "rs485_boot_port_config.h" #include "stm32g474xx.h" #include static bool fw(void){while(FLASH->SR&FLASH_SR_BSY){}if(FLASH->SR&(FLASH_SR_OPERR|FLASH_SR_PROGERR|FLASH_SR_WRPERR|FLASH_SR_PGAERR|FLASH_SR_SIZERR|FLASH_SR_PGSERR)){FLASH->SR=FLASH_SR_OPERR|FLASH_SR_PROGERR|FLASH_SR_WRPERR|FLASH_SR_PGAERR|FLASH_SR_SIZERR|FLASH_SR_PGSERR;return false;}return true;} static void ul(void){if(FLASH->CR&FLASH_CR_LOCK){FLASH->KEYR=0x45670123UL;FLASH->KEYR=0xCDEF89ABUL;}} static void lk(void){FLASH->CR|=FLASH_CR_LOCK;} void rs485_boot_hw_init(void){RCC->AHB2ENR|=RCC_AHB2ENR_GPIOAEN;RCC->APB2ENR|=RCC_APB2ENR_USART1EN;GPIOA->MODER=(GPIOA->MODER&~((3UL<<16)|(3UL<<18)|(3UL<<20)))|(1UL<<16)|(2UL<<18)|(2UL<<20);GPIOA->AFR[1]=(GPIOA->AFR[1]&~((0xFUL<<4)|(0xFUL<<8)))|(7UL<<4)|(7UL<<8);GPIOA->BSRR=1UL<<(RS485_BOOT_DE_PIN+16U);USART1->BRR=(RS485_BOOT_UART_CLOCK_HZ+RS485_BOOT_BAUDRATE/2U)/RS485_BOOT_BAUDRATE;USART1->CR1=USART_CR1_TE|USART_CR1_RE|USART_CR1_UE;} bool rs485_boot_hw_get_byte(uint8_t*b){uint32_t s=USART1->ISR;if(s&(USART_ISR_ORE|USART_ISR_FE|USART_ISR_NE)){USART1->ICR=USART_ICR_ORECF|USART_ICR_FECF|USART_ICR_NECF;return false;}if(!(s&USART_ISR_RXNE_RXFNE))return false;*b=(uint8_t)USART1->RDR;return true;} static bool tx(void*u,const uint8_t*d,uint16_t n){uint16_t i;(void)u;GPIOA->BSRR=1UL<ISR&USART_ISR_TXE_TXFNF)){}USART1->TDR=d[i];}while(!(USART1->ISR&USART_ISR_TC)){}USART1->ICR=USART_ICR_TCCF;GPIOA->BSRR=1UL<<(RS485_BOOT_DE_PIN+16U);return true;} static bool er(void*u,uint32_t n){uint32_t a,e;(void)u;if(!n||n>RS485_BOOT_FLASH_END-RS485_BOOT_APP_ADDRESS)return false;e=RS485_BOOT_APP_ADDRESS+((n+RS485_BOOT_FLASH_PAGE-1U)&~(RS485_BOOT_FLASH_PAGE-1U));ul();for(a=RS485_BOOT_APP_ADDRESS;aCR=(FLASH->CR&~(FLASH_CR_PNB_Msk|FLASH_CR_BKER))|FLASH_CR_PER|(pg<CR|=FLASH_CR_STRT;if(!fw()){lk();return false;}FLASH->CR&=~FLASH_CR_PER;}lk();return true;} static bool wr(void*u,uint32_t o,const uint8_t*d,uint16_t n){uint16_t z=0;(void)u;if((o&7U)||o+n>RS485_BOOT_FLASH_END-RS485_BOOT_APP_ADDRESS)return false;ul();while(z8)take=8;memcpy(&v,&d[z],take);FLASH->CR|=FLASH_CR_PG;*(volatile uint32_t*)(RS485_BOOT_APP_ADDRESS+o+z)=(uint32_t)v;*(volatile uint32_t*)(RS485_BOOT_APP_ADDRESS+o+z+4)=(uint32_t)(v>>32);if(!fw()){FLASH->CR&=~FLASH_CR_PG;lk();return false;}FLASH->CR&=~FLASH_CR_PG;z=(uint16_t)(z+take);}lk();return true;} static bool rd(void*u,uint32_t o,uint8_t*d,uint16_t n){(void)u;if(o+n>RS485_BOOT_FLASH_END-RS485_BOOT_APP_ADDRESS)return false;memcpy(d,(const void*)(RS485_BOOT_APP_ADDRESS+o),n);return true;} static bool ok(void*u,uint32_t n,uint32_t c){uint32_t sp=*(const uint32_t*)RS485_BOOT_APP_ADDRESS,rv=*(const uint32_t*)(RS485_BOOT_APP_ADDRESS+4);(void)u;return sp>=0x20000000UL&&sp<0x20020000UL&&(rv&1U)&&(rv&~1UL)>=RS485_BOOT_APP_ADDRESS&&(rv&~1UL)