feat(rs485-boot): add STM32F103 and G474 ports
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
#ifndef RS485_BOOT_PORT_CONFIG_H
|
||||
#define RS485_BOOT_PORT_CONFIG_H
|
||||
#define RS485_BOOT_BAUDRATE 512000UL
|
||||
#define RS485_BOOT_APP_ADDRESS 0x08003000UL
|
||||
#define RS485_BOOT_FLASH_END 0x08010000UL
|
||||
#define RS485_BOOT_FLASH_PAGE 1024UL
|
||||
#define RS485_BOOT_DE_PIN 8U /* USART1 PA9/PA10; DE PA8, active high. */
|
||||
#endif
|
||||
17
c/rs485-boot/ports/stm32f103/rs485_boot_stm32f103.c
Normal file
17
c/rs485-boot/ports/stm32f103/rs485_boot_stm32f103.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "rs485_boot_stm32f103.h"
|
||||
#include "rs485_boot_port_config.h"
|
||||
#include "stm32f10x.h"
|
||||
#include <string.h>
|
||||
static bool fw(void){while(FLASH->SR&FLASH_SR_BSY){}if(FLASH->SR&(FLASH_SR_PGERR|FLASH_SR_WRPRTERR)){FLASH->SR=FLASH_SR_PGERR|FLASH_SR_WRPRTERR|FLASH_SR_EOP;return false;}FLASH->SR=FLASH_SR_EOP;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){uint32_t c;RCC->APB2ENR|=RCC_APB2ENR_IOPAEN|RCC_APB2ENR_USART1EN;c=GPIOA->CRH;c&=~((0xFUL<<0)|(0xFUL<<4)|(0xFUL<<8));c|=(0x3UL<<0)|(0xBUL<<4)|(0x4UL<<8);GPIOA->CRH=c;GPIOA->BRR=1UL<<RS485_BOOT_DE_PIN;USART1->BRR=(SystemCoreClock+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->SR;if(s&(USART_SR_ORE|USART_SR_FE|USART_SR_NE)){(void)USART1->DR;return false;}if(!(s&USART_SR_RXNE))return false;*b=(uint8_t)USART1->DR;return true;}
|
||||
static bool tx(void*u,const uint8_t*d,uint16_t n){uint16_t i;(void)u;GPIOA->BSRR=1UL<<RS485_BOOT_DE_PIN;for(i=0;i<n;i++){while(!(USART1->SR&USART_SR_TXE)){}USART1->DR=d[i];}while(!(USART1->SR&USART_SR_TC)){}GPIOA->BRR=1UL<<RS485_BOOT_DE_PIN;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;a<e;a+=RS485_BOOT_FLASH_PAGE){FLASH->CR=FLASH_CR_PER;FLASH->AR=a;FLASH->CR|=FLASH_CR_STRT;if(!fw()){FLASH->CR=0;lk();return false;}}FLASH->CR=0;lk();return true;}
|
||||
static bool wr(void*u,uint32_t o,const uint8_t*d,uint16_t n){uint16_t i;(void)u;if((o&1U)||o+n>RS485_BOOT_FLASH_END-RS485_BOOT_APP_ADDRESS)return false;ul();for(i=0;i<n;i+=2){uint16_t v=(uint16_t)d[i]|(uint16_t)(i+1<n?((uint16_t)d[i+1]<<8):0xFF00U);volatile uint16_t*q=(volatile uint16_t*)(RS485_BOOT_APP_ADDRESS+o+i);FLASH->CR=FLASH_CR_PG;*q=v;if(!fw()||*q!=v){FLASH->CR=0;lk();return false;}}FLASH->CR=0;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<=0x20005000UL&&(rv&1U)&&(rv&~1UL)>=RS485_BOOT_APP_ADDRESS&&(rv&~1UL)<RS485_BOOT_FLASH_END&&rs485_boot_crc32((const uint8_t*)RS485_BOOT_APP_ADDRESS,n)==c;}
|
||||
static void reset(void*u){(void)u;NVIC_SystemReset();}
|
||||
rs485_boot_config_t rs485_boot_hw_config(void){rs485_boot_config_t c={RS485_BOOT_APP_ADDRESS,RS485_BOOT_FLASH_END-RS485_BOOT_APP_ADDRESS,RS485_BOOT_MAX_BLOCK};return c;}
|
||||
rs485_boot_port_t rs485_boot_hw_make_port(void){rs485_boot_port_t p={tx,er,wr,rd,ok,reset};return p;}
|
||||
8
c/rs485-boot/ports/stm32f103/rs485_boot_stm32f103.h
Normal file
8
c/rs485-boot/ports/stm32f103/rs485_boot_stm32f103.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef RS485_BOOT_STM32F103_H
|
||||
#define RS485_BOOT_STM32F103_H
|
||||
#include "rs485_boot.h"
|
||||
void rs485_boot_hw_init(void);
|
||||
bool rs485_boot_hw_get_byte(uint8_t *byte);
|
||||
rs485_boot_config_t rs485_boot_hw_config(void);
|
||||
rs485_boot_port_t rs485_boot_hw_make_port(void);
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef RS485_BOOT_PORT_CONFIG_H
|
||||
#define RS485_BOOT_PORT_CONFIG_H
|
||||
#define RS485_BOOT_BAUDRATE 512000UL
|
||||
#define RS485_BOOT_UART_CLOCK_HZ SystemCoreClock
|
||||
#define RS485_BOOT_APP_ADDRESS 0x08008000UL
|
||||
#define RS485_BOOT_FLASH_END 0x08080000UL
|
||||
#define RS485_BOOT_FLASH_PAGE 2048UL
|
||||
#define RS485_BOOT_DE_PIN 8U /* USART1 PA9/PA10 AF7; DE PA8. */
|
||||
#endif
|
||||
17
c/rs485-boot/ports/stm32g474vet/rs485_boot_stm32g474vet.c
Normal file
17
c/rs485-boot/ports/stm32g474vet/rs485_boot_stm32g474vet.c
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
#ifndef RS485_BOOT_STM32G474VET_H
|
||||
#define RS485_BOOT_STM32G474VET_H
|
||||
#include "rs485_boot.h"
|
||||
void rs485_boot_hw_init(void);
|
||||
bool rs485_boot_hw_get_byte(uint8_t *byte);
|
||||
rs485_boot_config_t rs485_boot_hw_config(void);
|
||||
rs485_boot_port_t rs485_boot_hw_make_port(void);
|
||||
#endif
|
||||
Reference in New Issue
Block a user