From 0c142bb60c76641b7d42226ce14525b801b9e4a6 Mon Sep 17 00:00:00 2001 From: R Date: Sat, 13 Apr 2024 21:33:56 +0100 Subject: [PATCH] reboot on complete file --- bootloader.c | 63 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/bootloader.c b/bootloader.c index 4cbae11..3c44e67 100644 --- a/bootloader.c +++ b/bootloader.c @@ -21,8 +21,8 @@ typedef struct USBD_descriptor { // EP 1 IN (64 bytes) // +0x140 // -// +0x1f0 -// stash copy of blockNo, numBlocks +// +0x1e0 +// ram for stashing data // +0x200 // <256-byte flash page buffer> @@ -159,8 +159,10 @@ const uint8_t ROOT_DIR[32 * 3] __attribute__((aligned(2))) = { #define USB_EP1_OUT(offs) (*(volatile uint32_t *)(0x40006040 + 2 * (offs))) #define USB_EP1_IN(offs) (*(volatile uint32_t *)(0x400060C0 + 2 * (offs))) -#define USB_UF2_FIELDS_STASH(offs) (*(volatile uint32_t *)(0x400061f0 + 2 * (offs))) -#define USB_SECTOR_STASH(offs) (*(volatile uint32_t *)(0x40006200 + 2 * (offs))) +#define USB_UF2_FIELDS_STASH(offs) (*(uint32_t *)(0x400061e0 + 2 * (offs))) +#define ACTIVE_CONFIG USB_UF2_FIELDS_STASH(12) +#define UF2_BLOCKS_LEFT USB_UF2_FIELDS_STASH(14) +#define USB_SECTOR_STASH(offs) (*(uint32_t *)(0x40006200 + 2 * (offs))) #define USB_EPTYPE_BULK 0b00 #define USB_EPTYPE_CONTROL 0b01 @@ -169,6 +171,8 @@ const uint8_t ROOT_DIR[32 * 3] __attribute__((aligned(2))) = { #define USB_STAT_STALL 0b01 #define USB_STAT_ACK 0b11 +#define R16_BKP_DATAR10 (*(volatile uint32_t*)0x40006C28) + #define R32_RCC_CTLR (*(volatile uint32_t*)0x40021000) #define R32_RCC_CFGR0 (*(volatile uint32_t*)0x40021004) #define R32_RCC_APB2PCENR (*(volatile uint32_t*)0x40021018) @@ -184,6 +188,8 @@ const uint8_t ROOT_DIR[32 * 3] __attribute__((aligned(2))) = { #define R32_EXTEN_CTR (*(volatile uint32_t*)0x40023800) +#define PFIC_SCTLR (*(volatile uint32_t*)0xE000ED10) + // state[7:0] = addr #define STATE_SET_ADDR 0x00 // state[15:8] = byte pos @@ -194,11 +200,13 @@ const uint8_t ROOT_DIR[32 * 3] __attribute__((aligned(2))) = { #define STATE_WANT_CBW 0x00 #define STATE_SENT_CSW 0x01 -#define STATE_SENT_DATA_IN 0x02 +#define STATE_SENT_CSW_REBOOT 0x02 +#define STATE_SENT_DATA_IN 0x03 +// state[10:8] = sector fragment +#define STATE_SEND_MORE_READ 0x04 // state[12] = uf2 good so far // state[10:8] = sector fragment -#define STATE_SEND_MORE_READ 0x03 -#define STATE_WAITING_FOR_WRITE 0x04 +#define STATE_WAITING_FOR_WRITE 0x05 __attribute__((always_inline)) static inline void set_ep_mode(uint32_t epidx, uint32_t epaddr, uint32_t eptype, uint32_t stat_rx, uint32_t stat_tx, uint32_t xtra, int clear_dtog) { uint32_t val = R16_USBD_EPR(epidx); @@ -270,6 +278,8 @@ __attribute__((always_inline)) static inline void synthesize_block(uint32_t bloc } __attribute__((naked)) int main(void) { + R16_BKP_DATAR10 = 0; + // PLL setup: system clock 96 MHz R32_EXTEN_CTR |= (1 << 4); // sneaky div2 R32_RCC_CFGR0 = (R32_RCC_CFGR0 & ~0xff0000) | (0b01101000 << 16); @@ -299,7 +309,7 @@ __attribute__((naked)) int main(void) { R32_EXTEN_CTR |= (1 << 1); uint32_t ctrl_xfer_state = 0; - uint32_t active_config = 0; + ACTIVE_CONFIG = 0; const uint8_t *outputting_desc = 0; uint32_t outputting_desc_sz = 0; @@ -312,10 +322,11 @@ __attribute__((naked)) int main(void) { // [31:0] = current lba // [15:0] = blocks left // when writing: - // [31:0] = num uf2 blocks left // [15:0] = blocks left uint32_t scsi_xfer_lba_blocks = 0; + UF2_BLOCKS_LEFT = 0; + while (1) { uint32_t usb_int_status = R16_USBD_ISTR; if (usb_int_status & (1 << 10)) { @@ -397,7 +408,7 @@ __attribute__((naked)) int main(void) { } } else if (bRequest_bmRequestType == 0x0880) { // GET_CONFIGURATION - USB_EP0_IN(0) = active_config; + USB_EP0_IN(0) = ACTIVE_CONFIG; USB_DESCS[0].count_tx = min(1, wLength); ctrl_xfer_state = (STATE_CTRL_SIMPLE_IN << 24); set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); @@ -405,7 +416,7 @@ __attribute__((naked)) int main(void) { // SET_CONFIGURATION uint32_t wValue = USB_EP0_OUT(2); if (wValue == 0 || wValue == 1) { - active_config = wValue; + ACTIVE_CONFIG = wValue; USB_DESCS[0].count_tx = 0; set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); if (wValue) { @@ -698,13 +709,13 @@ error_csw: USB_UF2_FIELDS_STASH(2) = USB_EP1_OUT(22); USB_UF2_FIELDS_STASH(4) = USB_EP1_OUT(24); USB_UF2_FIELDS_STASH(6) = USB_EP1_OUT(26); + USB_UF2_FIELDS_STASH(8) = USB_EP1_OUT(12); + USB_UF2_FIELDS_STASH(10) = USB_EP1_OUT(14); for (int i = 0; i < 16; i++) USB_SECTOR_STASH(i * 2) = USB_EP1_OUT(32 + i * 2); msc_state += 0x1000; - // uint32_t blocknum = USB_EP1_OUT(20) | (USB_EP1_OUT(22) << 16); - // uint32_t totblocks = USB_EP1_OUT(24) | (USB_EP1_OUT(26) << 16); } } } @@ -721,14 +732,19 @@ error_csw: msc_state += 0x100; } else { // full sector is done - uint32_t uf2_blocks_left = scsi_xfer_lba_blocks >> 16; - if (msc_state & 0x1000) { if (USB_EP1_OUT(60) == 0x6F30 && USB_EP1_OUT(62) == 0x0AB1) { // uf2 all magics are good! uint32_t blocknum = USB_UF2_FIELDS_STASH(0) | (USB_UF2_FIELDS_STASH(2) << 16); uint32_t totblocks = USB_UF2_FIELDS_STASH(4) | (USB_UF2_FIELDS_STASH(6) << 16); - while (1) asm volatile("nop"); // todo + uint32_t address = USB_UF2_FIELDS_STASH(8) | (USB_UF2_FIELDS_STASH(10) << 16); + + if (UF2_BLOCKS_LEFT == 0) + UF2_BLOCKS_LEFT = (totblocks - 1) | 0x8000; + else + UF2_BLOCKS_LEFT--; + + // todo flash the file } } @@ -744,9 +760,12 @@ error_csw: USB_EP1_IN(12) = 0; USB_DESCS[1].count_tx = 13; set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_STALL, USB_STAT_ACK, 0, 0); - msc_state = STATE_SENT_CSW; + if (UF2_BLOCKS_LEFT == 0x8000) + msc_state = STATE_SENT_CSW_REBOOT; + else + msc_state = STATE_SENT_CSW; } else { - scsi_xfer_lba_blocks = (uf2_blocks_left << 16) | blocks_left; + scsi_xfer_lba_blocks = blocks_left; set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 0); msc_state = STATE_WAITING_FOR_WRITE; } @@ -760,6 +779,14 @@ error_csw: set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 0); msc_state = (msc_state & 0xffffff00) | STATE_WANT_CBW; break; + case STATE_SENT_CSW_REBOOT: + // todo reboot into ram + for (int i = 0; i < 1000000; i++) + asm volatile(""); + R32_EXTEN_CTR &= ~(1 << 1); + PFIC_SCTLR = 0x80000000; + while (1) { asm volatile(""); } + break; case STATE_SENT_DATA_IN: USB_EP1_IN(0) = 0x5355; USB_EP1_IN(2) = 0x5342;