Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Timeout for inactivity. Support for SET_ADDRESS. Support for stm32g491. Support for ERASE_PAGE. #54

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ FWTARGETS += stm32l433xb stm32l433xc
FWTARGETS += stm32f070x6 stm32f070xb stm32f072x8
FWTARGETS += stm32g431x6 stm32g431x8 stm32g431xb
FWTARGETS += stm32g474xb stm32g474xc stm32g474xe
FWTARGETS += stm32g491xe stm32g491xc stm32g4a1xe stm32g4a1xc
FWTARGETS += stm32f446xc stm32f446xc_hs stm32f446xe stm32f446xe_hs
FWTARGETS += stm32f405xg stm32f405xg_hs

Expand Down Expand Up @@ -555,6 +556,30 @@ stm32g474xe :
FWDEFS='STM32G4 STM32G474xx USBD_ASM_DRIVER' \
LDPARAMS='ROMLEN=512K RAMLEN=96K APPALIGN=0x1000'

stm32g491xe :
${MAKE} bootloader FWCPU='-mcpu=cortex-m4' \
FWSTARTUP='mcu/stm32g4xx.S' \
FWDEFS='STM32G4 STM32G491xx USBD_ASM_DRIVER' \
LDPARAMS='ROMLEN=512K RAMLEN=96K APPALIGN=0x4000'

stm32g491xc :
${MAKE} bootloader FWCPU='-mcpu=cortex-m4' \
FWSTARTUP='mcu/stm32g4xx.S' \
FWDEFS='STM32G4 STM32G491xx USBD_ASM_DRIVER' \
LDPARAMS='ROMLEN=256K RAMLEN=96K APPALIGN=0x4000'

stm32g4a1xe :
${MAKE} bootloader FWCPU='-mcpu=cortex-m4' \
FWSTARTUP='mcu/stm32g4xx.S' \
FWDEFS='STM32G4 STM32G491xx USBD_ASM_DRIVER' \
LDPARAMS='ROMLEN=512K RAMLEN=96K APPALIGN=0x4000'

stm32g4a1xc :
${MAKE} bootloader FWCPU='-mcpu=cortex-m4' \
FWSTARTUP='mcu/stm32g4xx.S' \
FWDEFS='STM32G4 STM32G491xx USBD_ASM_DRIVER' \
LDPARAMS='ROMLEN=256K RAMLEN=96K APPALIGN=0x4000'

stm32f446xc :
$(MAKE) bootloader FWCPU='-mcpu=cortex-m4' \
FWSTARTUP='mcu/stm32f4xx.S' \
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ The bootloader can be configured through the make parameters. See CONFIG.md for
| stm32g474xb | STM32G471xB, STM32G473xB, STM32G474xB, STM32G483xB | |
| stm32g474xc | STM32G471xC, STM32G473xC, STM32G474xC, STM32G483xC | |
| stm32g474xe | STM32G471xE, STM32G473xE, STM32G474xE, STM32G483xE | tested G747RE |
| stm32g491xe | STM32G491xE, STM32G4A1xE |
| stm32g491xc | STM32G491xC, STM32G4A1xC |
| stm32f303xe | STM32F303xE | tested |
| stm32f373xc | STM32F373xC | tested |

Expand Down
15 changes: 15 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,15 @@
#define DFU_DSC_FLASH _ENABLE
#endif
#ifndef DFU_STR_FLASH
#if defined(STM32G491xx) //Cat4
// NB: overstated for STM32G4x1xc which is only 256K
#define DFU_STR_FLASH "Internal flash/0x08000000/256*2KE"
#elif defined(STM32F429xx)
#define DFU_STR_FLASH "Internal flash/0x08000000/4*16KE,1*64KE,6*128KE,4*16KE,1*64KE,6*128KE"
#else
#define DFU_STR_FLASH "Internal flash"
#endif
#endif
/* USB string for DFU EEPROM interface sreing descriptor */
#ifndef DFU_DSC_EEPROM
#define DFU_DSC_EEPROM _ENABLE
Expand All @@ -128,14 +135,22 @@
#define DFU_EP0_SIZE 8
/* DFU properties */
#ifndef DFU_POLL_TIMEOUT
#if defined(STM32G491xx) //Cat4
#define DFU_POLL_TIMEOUT 50
#else
#define DFU_POLL_TIMEOUT 20
#endif
#endif
#ifndef DFU_DETACH_TIMEOUT
#define DFU_DETACH_TIMEOUT 200
#endif
#ifndef DFU_BLOCKSZ
#if defined(STM32G491xx) //Cat4
#define DFU_BLOCKSZ 0x800
#else
#define DFU_BLOCKSZ 0x80
#endif
#endif
/* 32 bit DFU bootkey value */
#ifndef DFU_BOOTKEY
#define DFU_BOOTKEY 0x157F32D4
Expand Down
4 changes: 4 additions & 0 deletions mcu/stm32g4xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ program_flash:
/* calculating PNB[6:0]: ADDR[17:11] -> CR[9:3] */
lsrs r4, 11
bfi r5, r4, 3, 7
#elif defined(STM32G491xx) //Cat4
/* calculating PNB[7:0]: ADDR[18:11] -> CR[10:3] */
lsrs r4, 11
bfi r5, r4, 3, 8
#else // Cat3
/* check dual bank */
ldr r5, [r3, FLASH_OPTR]
Expand Down
57 changes: 55 additions & 2 deletions src/bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ static struct dfu_data_s {
uint8_t interface;
uint8_t bStatus;
uint8_t bState;
#if defined(DFU_WATCHDOG)
uint32_t counter;
#endif
} dfu_data;

/** Processing DFU_SET_IDLE request */
Expand All @@ -100,6 +103,27 @@ static usbd_respond dfu_set_idle(void) {

extern void System_Reset(void);

static inline void heartbeat(void) {
#if defined(DFU_WATCHDOG)
dfu_data.counter = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = SysTick->LOAD = (1ULL << 24) - 1;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
#endif
}

static inline void watchdog(void) {
#if defined(DFU_WATCHDOG)
if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) {
dfu_data.counter++;
}
if ((((uint64_t)dfu_data.counter << 24)
| (~SysTick->VAL & ((1ULL << 24) - 1))) > DFU_WATCHDOG) {
System_Reset();
}
#endif
}

static usbd_respond dfu_err_badreq(void) {
dfu_data.bState = USB_DFU_STATE_DFU_ERROR;
dfu_data.bStatus = USB_DFU_STATUS_ERR_STALLEDPKT;
Expand Down Expand Up @@ -142,8 +166,33 @@ static usbd_respond dfu_dnload(void *buf, size_t blksize) {
dfu_data.bState = USB_DFU_STATE_DFU_ERROR;
return usbd_ack;
}
aes_decrypt(buf, buf, blksize );
dfu_data.bStatus = dfu_data.flash(dfu_data.dptr, buf, blksize);
if (blksize == 5) {
uint8_t *cp = buf;
uint8_t command = *cp;
if ((command == 0x21) /* SET_ADDRESS command */
|| (command == 0x41)) { /* ERASE_PAGE command */
uint32_t address = cp[1]
| ((uint16_t)cp[2] << 8)
| ((uint32_t)cp[3] << 16)
| ((uint32_t)cp[4] << 24);
if (command == 0x41) { /* ERASE_PAGE command */
*((uint64_t*)buf) = -1LL;
dfu_data.bStatus = dfu_data.flash(
(void*)(uintptr_t)address,
buf,
sizeof(uint64_t));
} else { /* SET_ADDRESS command */
dfu_data.dptr = (void*)(uintptr_t)address;
dfu_data.bStatus = USB_DFU_STATUS_OK;
}
blksize = 0;
} else {
dfu_data.bStatus = USB_DFU_STATUS_ERR_TARGET;
}
} else {
aes_decrypt(buf, buf, blksize);
dfu_data.bStatus = dfu_data.flash(dfu_data.dptr, buf, blksize);
}

if (dfu_data.bStatus == USB_DFU_STATUS_OK) {
dfu_data.dptr += blksize;
Expand Down Expand Up @@ -223,6 +272,7 @@ static void dfu_reset(usbd_device *dev, uint8_t ev, uint8_t ep) {
}

static usbd_respond dfu_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) {
heartbeat();
(void)callback;
if ((req->bmRequestType & (USB_REQ_TYPE | USB_REQ_RECIPIENT)) == (USB_REQ_STANDARD | USB_REQ_INTERFACE)) {
switch (req->bRequest) {
Expand Down Expand Up @@ -287,6 +337,7 @@ static usbd_respond dfu_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_ca


static usbd_respond dfu_config(usbd_device *dev, uint8_t config) {
heartbeat();
switch (config) {
case 0:
usbd_reg_event(dev, usbd_evt_reset, 0);
Expand All @@ -313,7 +364,9 @@ static void dfu_init (void) {

int main (void) {
dfu_init();
heartbeat();
while(1) {
usbd_poll(&dfu);
watchdog();
}
}