diff --git a/32blit-stm32/CMakeLists.txt b/32blit-stm32/CMakeLists.txt index 68afa74d1..0a4fb139b 100644 --- a/32blit-stm32/CMakeLists.txt +++ b/32blit-stm32/CMakeLists.txt @@ -39,8 +39,6 @@ list(APPEND SOURCES Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_jpeg.c Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hcd.c Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c - Middlewares/Third_Party/FatFs/src/diskio.c - Middlewares/Third_Party/FatFs/src/ff_gen_drv.c ../3rd-party/fatfs/ff.c ../3rd-party/fatfs/ffsystem.c ../3rd-party/fatfs/ffunicode.c @@ -58,8 +56,7 @@ list(APPEND SOURCES Middlewares/ST/STM32_USB_Host_Library/Class/CDC/Src/usbh_cdc.c Src/usbd_msc_scsi.c Src/system_stm32h7xx.c - Src/user_diskio.c - Src/fatfs.c + Src/fatfs.cpp Src/fatfs_sd.c Src/usb_otg.c Src/usb_device.c @@ -131,7 +128,6 @@ set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/STM32H7xx/Include ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Middlewares/Third_Party/FatFs/src ${CMAKE_CURRENT_SOURCE_DIR}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc ${CMAKE_CURRENT_SOURCE_DIR}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc ${CMAKE_CURRENT_SOURCE_DIR}/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc @@ -162,9 +158,6 @@ target_include_directories(BlitHalSTM32 target_compile_definitions(BlitHalSTM32 PRIVATE ${DEFINITIONS} - -DAPPLICATION_VTOR=${APPLICATION_VTOR} - -DEXTERNAL_LOAD_ADDRESS=${EXTERNAL_LOAD_ADDRESS} - -DINITIALISE_QSPI=${INITIALISE_QSPI} -DCDC_FIFO_BUFFERS=${CDC_FIFO_BUFFERS} ) diff --git a/32blit-stm32/Inc/CDCCommandStream.h b/32blit-stm32/Inc/CDCCommandStream.h index 646251e27..ec952fcbf 100644 --- a/32blit-stm32/Inc/CDCCommandStream.h +++ b/32blit-stm32/Inc/CDCCommandStream.h @@ -50,9 +50,9 @@ class CDCCommandStream StreamState m_state; - uint8_t m_header[4] = { '3', '2', 'B', 'L' }; uint8_t m_uHeaderScanPos = 0; uint8_t m_uCommandScanPos = 0; + uint8_t m_uRetryCount = 0; CDCCommandHandler::CDCFourCC uCommand = 0; @@ -63,9 +63,6 @@ class CDCCommandStream CDCDataStream m_dataStream; - uint8_t m_uRetryCount = 0; - - CDCFifoElement m_fifoElements[CDC_FIFO_BUFFERS]; uint8_t m_uFifoReadPos; uint8_t m_uFifoWritePos; diff --git a/32blit-stm32/Inc/display.hpp b/32blit-stm32/Inc/display.hpp index 1d11c0cc9..eb654bccf 100644 --- a/32blit-stm32/Inc/display.hpp +++ b/32blit-stm32/Inc/display.hpp @@ -30,17 +30,6 @@ namespace display { SurfaceInfo &set_screen_mode(ScreenMode new_mode); void set_screen_palette(const Pen *colours, int num_cols); bool set_screen_mode_format(ScreenMode new_mode, SurfaceTemplate &new_surf_template); - - void flip(const Surface &source); - - void screen_init(); - void ltdc_init(); - - uint32_t get_dma2d_count(void); - - void dma2d_lores_flip_step2(void); - void dma2d_lores_flip_step3(void); - void dma2d_lores_flip_step4(void); } diff --git a/32blit-stm32/Inc/fatfs.h b/32blit-stm32/Inc/fatfs.h deleted file mode 100644 index 1c7f702f7..000000000 --- a/32blit-stm32/Inc/fatfs.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * @file fatfs.h - * @brief Header for fatfs applications - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __fatfs_H -#define __fatfs_H -#ifdef __cplusplus - extern "C" { -#endif - -#include "ff.h" -#include "ff_gen_drv.h" -#include "user_diskio.h" /* defines USER_Driver as external */ - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern uint8_t retUSER; /* Return value for USER */ -extern char USERPath[4]; /* USER logical drive path */ -extern FATFS USERFatFS; /* File system object for USER logical drive */ -extern FIL USERFile; /* File object for USER */ - -void MX_FATFS_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ -#ifdef __cplusplus -} -#endif -#endif /*__fatfs_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/32blit-stm32/Inc/gpio.hpp b/32blit-stm32/Inc/gpio.hpp index ec7e33714..37be6d49a 100644 --- a/32blit-stm32/Inc/gpio.hpp +++ b/32blit-stm32/Inc/gpio.hpp @@ -1,15 +1,27 @@ #ifndef __PIN_CONFIGURATION_H #define __PIN_CONFIGURATION_H +#include + #include "main.h" #include "gpio_defs.h" namespace gpio { - // initialises all of the pins of the MCU into the correct - // configuration for 32blit + // initialises all of the pins of the MCU into the correct + // configuration for 32blit void init(); + inline bool read(GPIO_TypeDef *port, uint16_t pins) { + return port->IDR & pins; + } + + inline void write(GPIO_TypeDef *port, uint16_t pins, bool value) { + if(value) + port->BSRR = pins; + else + port->BSRR = pins << 16; + } } -#endif \ No newline at end of file +#endif diff --git a/32blit-stm32/Inc/main.h b/32blit-stm32/Inc/main.h index 4cbcf4aa0..c85a2f409 100644 --- a/32blit-stm32/Inc/main.h +++ b/32blit-stm32/Inc/main.h @@ -66,10 +66,7 @@ extern uint8_t charge_led_b; /* Private defines -----------------------------------------------------------*/ /* USER CODE BEGIN Private defines */ -#define HIGH(PORT, PIN) HAL_GPIO_WritePin(PORT, PIN, GPIO_PIN_SET); -#define LOW(PORT, PIN) HAL_GPIO_WritePin(PORT, PIN, GPIO_PIN_RESET); -#define DELAY(MS) HAL_Delay(MS) /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/32blit-stm32/Inc/quadspi.h b/32blit-stm32/Inc/quadspi.h index 81b7bd79a..3e9e69bfc 100644 --- a/32blit-stm32/Inc/quadspi.h +++ b/32blit-stm32/Inc/quadspi.h @@ -36,7 +36,7 @@ extern QSPI_HandleTypeDef hqspi; #define APPLICATION_ADDRESS QSPI_BASE // Flash example -#define QSPI_FLASH_SIZE POSITION_VAL(0x2000000)-1 +#define QSPI_FLASH_SIZE __builtin_ctz(0x2000000)-1 #define QSPI_PAGE_SIZE 256 /* Reset Operations */ diff --git a/32blit-stm32/Inc/quadspi.hpp b/32blit-stm32/Inc/quadspi.hpp new file mode 100644 index 000000000..87fc38612 --- /dev/null +++ b/32blit-stm32/Inc/quadspi.hpp @@ -0,0 +1,9 @@ +#pragma once +#include + +constexpr uint32_t qspi_flash_sector_size = 64 * 1024; +constexpr uint32_t qspi_flash_size = 32768 * 1024; +constexpr uint32_t qspi_flash_address = 0x90000000; + +// resevered space for temp/cached files +constexpr uint32_t qspi_tmp_reserved = 4 * 1024 * 1024; diff --git a/32blit-stm32/Inc/spi-st7272a.h b/32blit-stm32/Inc/spi-st7272a.h index 326559672..ef0ef8e4b 100644 --- a/32blit-stm32/Inc/spi-st7272a.h +++ b/32blit-stm32/Inc/spi-st7272a.h @@ -5,8 +5,11 @@ #define ST7272A_DISPLAY_MODE_REGISTER 0x19 #define ST7272A_DISPLAY_MODE_DEFAULT 0xec // 0b11101100 VA Mode, Top/Bottom & Left/Right scan, Negative polarity VSync/HSync pulses +#define HIGH(PORT, PIN) HAL_GPIO_WritePin(PORT, PIN, GPIO_PIN_SET); +#define LOW(PORT, PIN) HAL_GPIO_WritePin(PORT, PIN, GPIO_PIN_RESET); + #define ST7272A_CS(active) if(active) {LOW(LCD_CS_GPIO_Port, LCD_CS_Pin)} else {HIGH(LCD_CS_GPIO_Port, LCD_CS_Pin)} -#define ST7272A_RESET() LOW(LCD_RESET_GPIO_Port, LCD_RESET_Pin); DELAY(100); HIGH(LCD_RESET_GPIO_Port, LCD_RESET_Pin); DELAY(100); +#define ST7272A_RESET() LOW(LCD_RESET_GPIO_Port, LCD_RESET_Pin); HAL_Delay(100); HIGH(LCD_RESET_GPIO_Port, LCD_RESET_Pin); HAL_Delay(100); #ifdef __cplusplus extern "C" { @@ -18,4 +21,4 @@ extern void st7272a_set_bgr(); } #endif -#endif \ No newline at end of file +#endif diff --git a/32blit-stm32/Middlewares/Third_Party/FatFs/src/diskio.c b/32blit-stm32/Middlewares/Third_Party/FatFs/src/diskio.c deleted file mode 100644 index 4243fd59e..000000000 --- a/32blit-stm32/Middlewares/Third_Party/FatFs/src/diskio.c +++ /dev/null @@ -1,105 +0,0 @@ -/*-----------------------------------------------------------------------*/ -/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */ -/*-----------------------------------------------------------------------*/ -/* If a working storage control module is available, it should be */ -/* attached to the FatFs via a glue function rather than modifying it. */ -/* This is an example of glue functions to attach various exsisting */ -/* storage control modules to the FatFs module with a defined API. */ -/*-----------------------------------------------------------------------*/ - -#include "ff.h" /* Obtains integer types */ -#include "diskio.h" /* Declarations of disk functions */ -#include "ff_gen_drv.h" - - -extern Disk_drvTypeDef disk; - -/*-----------------------------------------------------------------------*/ -/* Get Drive Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat; - stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]); - return stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Inidialize a Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat = RES_OK; - - if(disk.is_initialized[pdrv] == 0) - { - disk.is_initialized[pdrv] = 1; - stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]); - } - return stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - LBA_t sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ -) -{ - DRESULT res; - res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count); - return res; -} - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -#if FF_FS_READONLY == 0 - -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - LBA_t sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ -) -{ - DRESULT res; - res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count); - return res; -} - -#endif - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - DRESULT res; - res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff); - return res; -} - diff --git a/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.c b/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.c deleted file mode 100644 index 0322edfc7..000000000 --- a/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - ****************************************************************************** - * @file ff_gen_drv.c - * @author MCD Application Team - * @brief FatFs generic low level driver. - ***************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** -**/ -/* Includes ------------------------------------------------------------------*/ -#include "ff_gen_drv.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -Disk_drvTypeDef disk = {{0},{0},{0},0}; - -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief Links a compatible diskio driver/lun id and increments the number of active - * linked drivers. - * @note The number of linked drivers (volumes) is up to 10 due to FatFs limits. - * @param drv: pointer to the disk IO Driver structure - * @param path: pointer to the logical drive path - * @param lun : only used for USB Key Disk to add multi-lun management - else the parameter must be equal to 0 - * @retval Returns 0 in case of success, otherwise 1. - */ -uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, uint8_t lun) -{ - uint8_t ret = 1; - uint8_t DiskNum = 0; - - if(disk.nbr < FF_VOLUMES) - { - disk.is_initialized[disk.nbr] = 0; - disk.drv[disk.nbr] = drv; - disk.lun[disk.nbr] = lun; - DiskNum = disk.nbr++; - path[0] = DiskNum + '0'; - path[1] = ':'; - path[2] = '/'; - path[3] = 0; - ret = 0; - } - - return ret; -} - -/** - * @brief Links a compatible diskio driver and increments the number of active - * linked drivers. - * @note The number of linked drivers (volumes) is up to 10 due to FatFs limits - * @param drv: pointer to the disk IO Driver structure - * @param path: pointer to the logical drive path - * @retval Returns 0 in case of success, otherwise 1. - */ -uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path) -{ - return FATFS_LinkDriverEx(drv, path, 0); -} - -/** - * @brief Unlinks a diskio driver and decrements the number of active linked - * drivers. - * @param path: pointer to the logical drive path - * @param lun : not used - * @retval Returns 0 in case of success, otherwise 1. - */ -uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun) -{ - uint8_t DiskNum = 0; - uint8_t ret = 1; - - if(disk.nbr >= 1) - { - DiskNum = path[0] - '0'; - if(disk.drv[DiskNum] != 0) - { - disk.drv[DiskNum] = 0; - disk.lun[DiskNum] = 0; - disk.nbr--; - ret = 0; - } - } - - return ret; -} - -/** - * @brief Unlinks a diskio driver and decrements the number of active linked - * drivers. - * @param path: pointer to the logical drive path - * @retval Returns 0 in case of success, otherwise 1. - */ -uint8_t FATFS_UnLinkDriver(char *path) -{ - return FATFS_UnLinkDriverEx(path, 0); -} - -/** - * @brief Gets number of linked drivers to the FatFs module. - * @param None - * @retval Number of attached drivers. - */ -uint8_t FATFS_GetAttachedDriversNbr(void) -{ - return disk.nbr; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.h b/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.h deleted file mode 100644 index f832ebf5f..000000000 --- a/32blit-stm32/Middlewares/Third_Party/FatFs/src/ff_gen_drv.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - ****************************************************************************** - * @file ff_gen_drv.h - * @author MCD Application Team - * @brief Header for ff_gen_drv.c module. - ***************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** -**/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __FF_GEN_DRV_H -#define __FF_GEN_DRV_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "ff.h" -#include "diskio.h" -#include "stdint.h" - -#define _USE_WRITE 1 /* 1: Enable disk_write function */ -#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */ - - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief Disk IO Driver structure definition - */ -typedef struct -{ - DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */ - DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */ - DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */ -#if _USE_WRITE == 1 - DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */ -#endif /* _USE_WRITE == 1 */ -#if _USE_IOCTL == 1 - DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */ -#endif /* _USE_IOCTL == 1 */ - -}Diskio_drvTypeDef; - -/** - * @brief Global Disk IO Drivers structure definition - */ -typedef struct -{ - uint8_t is_initialized[FF_VOLUMES]; - const Diskio_drvTypeDef *drv[FF_VOLUMES]; - uint8_t lun[FF_VOLUMES]; - volatile uint8_t nbr; - -}Disk_drvTypeDef; - -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path); -uint8_t FATFS_UnLinkDriver(char *path); -uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun); -uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun); -uint8_t FATFS_GetAttachedDriversNbr(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __FF_GEN_DRV_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/32blit-stm32/Src/32blit.cpp b/32blit-stm32/Src/32blit.cpp index 5bf5d5cd1..1e6f50e56 100644 --- a/32blit-stm32/Src/32blit.cpp +++ b/32blit-stm32/Src/32blit.cpp @@ -13,10 +13,11 @@ #include "executable.hpp" #include "multiplayer.hpp" #include "power.hpp" +#include "quadspi.hpp" #include "tim.h" #include "rng.h" -#include "fatfs.h" +#include "ff.h" #include "quadspi.h" #include "usbd_core.h" #include "USBManager.h" @@ -32,7 +33,6 @@ extern USBD_HandleTypeDef hUsbDeviceHS; extern USBManager g_usbManager; FATFS filesystem; -extern Disk_drvTypeDef disk; static bool fs_mounted = false; bool exit_game = false; @@ -208,8 +208,6 @@ void blit_tick() { fs_mounted = f_mount(&filesystem, "", 1) == FR_OK; else fs_mounted = false; - - disk.is_initialized[0] = fs_mounted; // this gets set without checking if the init succeeded, un-set it if the init failed (or the card was removed) } auto time_to_next_tick = do_tick(blit::now()); @@ -232,7 +230,7 @@ void blit_tick() { } bool blit_sd_detected() { - return HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == 1; + return gpio::read(GPIOD, GPIO_PIN_11); } bool blit_sd_mounted() { @@ -260,38 +258,42 @@ void blit_update_volume() { } static void save_screenshot() { - int index = 0; - char buf[200]; - std::string app_name; - const std::string screenshots_dir_name = "screenshots"; + const char *app_name; + const char *screenshots_dir_name = "screenshots"; + + char buf[10]; - if(!blit_user_code_running()) { + // get title + if(!blit_user_code_running()) app_name = "_firmware"; - } else { + else { auto meta = blit_get_running_game_metadata(); - if(meta) { + if(meta) app_name = meta->title; - } else { + else { // fallback to offset - app_name = std::to_string(persist.last_game_offset); + snprintf(buf, 10, "%li", persist.last_game_offset); + app_name = buf; } } - do { - snprintf(buf, 200, "%s/%s%i.bmp", screenshots_dir_name.c_str(), app_name.c_str(), index); + if(!::directory_exists(screenshots_dir_name)) + ::create_directory(screenshots_dir_name); - if(!::directory_exists(screenshots_dir_name)){ - ::create_directory(screenshots_dir_name); - } + int index = 0; + char screenshot_filename[200]; - if(!::file_exists(buf)) + do { + snprintf(screenshot_filename, 200, "%s/%s%i.bmp", screenshots_dir_name, app_name, index); + + if(!::file_exists(screenshot_filename)) break; index++; } while(true); - screen.save(buf); + screen.save(screenshot_filename); } void blit_init() { @@ -322,11 +324,9 @@ void blit_init() { memset(&__ltdc_start, 0, len); } -#if (INITIALISE_QSPI==1) // don't switch to game if it crashed, or home is held - if(persist.reset_target == prtGame && (HAL_GPIO_ReadPin(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin) || persist.reset_error)) + if(persist.reset_target == prtGame && (gpio::read(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin) || persist.reset_error)) persist.reset_target = prtFirmware; -#endif init_api_shared(); @@ -524,7 +524,7 @@ void blit_update_led() { void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim == &htim2) { - bool pressed = HAL_GPIO_ReadPin(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin); + bool pressed = gpio::read(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin); if(pressed && blit_user_code_running()) { // if button was pressed and we are inside a game, queue the game exit exit_game = true; } @@ -533,7 +533,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { - bool pressed = HAL_GPIO_ReadPin(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin); + bool pressed = gpio::read(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin); if(pressed) { /* The timer will generate a spurious interrupt as soon as it's enabled- apparently to load the compare value. @@ -567,17 +567,17 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { void blit_process_input() { // Read buttons blit::buttons = - (!HAL_GPIO_ReadPin(DPAD_UP_GPIO_Port, DPAD_UP_Pin) ? uint32_t(DPAD_UP) : 0) | - (!HAL_GPIO_ReadPin(DPAD_DOWN_GPIO_Port, DPAD_DOWN_Pin) ? uint32_t(DPAD_DOWN) : 0) | - (!HAL_GPIO_ReadPin(DPAD_LEFT_GPIO_Port, DPAD_LEFT_Pin) ? uint32_t(DPAD_LEFT) : 0) | - (!HAL_GPIO_ReadPin(DPAD_RIGHT_GPIO_Port, DPAD_RIGHT_Pin) ? uint32_t(DPAD_RIGHT) : 0) | - (!HAL_GPIO_ReadPin(BUTTON_A_GPIO_Port, BUTTON_A_Pin) ? uint32_t(A) : 0) | - (!HAL_GPIO_ReadPin(BUTTON_B_GPIO_Port, BUTTON_B_Pin) ? uint32_t(B) : 0) | - (!HAL_GPIO_ReadPin(BUTTON_X_GPIO_Port, BUTTON_X_Pin) ? uint32_t(X) : 0) | - (!HAL_GPIO_ReadPin(BUTTON_Y_GPIO_Port, BUTTON_Y_Pin) ? uint32_t(Y) : 0) | - (HAL_GPIO_ReadPin(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin) ? uint32_t(HOME) : 0) | // INVERTED LOGIC! - (!HAL_GPIO_ReadPin(BUTTON_MENU_GPIO_Port, BUTTON_MENU_Pin) ? uint32_t(MENU) : 0) | - (!HAL_GPIO_ReadPin(JOYSTICK_BUTTON_GPIO_Port, JOYSTICK_BUTTON_Pin) ? uint32_t(JOYSTICK) : 0); + (!gpio::read(DPAD_UP_GPIO_Port, DPAD_UP_Pin) ? uint32_t(DPAD_UP) : 0) | + (!gpio::read(DPAD_DOWN_GPIO_Port, DPAD_DOWN_Pin) ? uint32_t(DPAD_DOWN) : 0) | + (!gpio::read(DPAD_LEFT_GPIO_Port, DPAD_LEFT_Pin) ? uint32_t(DPAD_LEFT) : 0) | + (!gpio::read(DPAD_RIGHT_GPIO_Port, DPAD_RIGHT_Pin) ? uint32_t(DPAD_RIGHT) : 0) | + (!gpio::read(BUTTON_A_GPIO_Port, BUTTON_A_Pin) ? uint32_t(A) : 0) | + (!gpio::read(BUTTON_B_GPIO_Port, BUTTON_B_Pin) ? uint32_t(B) : 0) | + (!gpio::read(BUTTON_X_GPIO_Port, BUTTON_X_Pin) ? uint32_t(X) : 0) | + (!gpio::read(BUTTON_Y_GPIO_Port, BUTTON_Y_Pin) ? uint32_t(Y) : 0) | + ( gpio::read(BUTTON_HOME_GPIO_Port, BUTTON_HOME_Pin) ? uint32_t(HOME) : 0) | // INVERTED LOGIC! + (!gpio::read(BUTTON_MENU_GPIO_Port, BUTTON_MENU_Pin) ? uint32_t(MENU) : 0) | + (!gpio::read(JOYSTICK_BUTTON_GPIO_Port, JOYSTICK_BUTTON_Pin) ? uint32_t(JOYSTICK) : 0); if(blit::buttons.state) power::update_active(); @@ -652,107 +652,52 @@ bool blit_switch_execution(uint32_t address, bool force_game) } // switch to user app in external flash - if(EXTERNAL_LOAD_ADDRESS >= 0x90000000) { - qspi_enable_memorymapped_mode(); - - auto game_header = ((__IO BlitGameHeader *) (EXTERNAL_LOAD_ADDRESS + address)); - - if(game_header->magic == blit_game_magic) { - - persist.last_game_offset = address; - - // game possibly running, wait until it isn't - if(user_tick && !user_code_disabled) { - game_switch_requested = true; - return true; - } - - // avoid starting a game disabled (will break sound and the menu) - if(user_code_disabled) - blit_enable_user_code(); - - cached_file_in_tmp = false; - close_open_files(); + qspi_enable_memorymapped_mode(); - // load function pointers - auto init = (BlitInitFunction)((uint8_t *)game_header->init + address); + auto game_header = ((__IO BlitGameHeader *) (qspi_flash_address + address)); - // set these up early so that blit_user_code_running works in code called from init - user_render = (BlitRenderFunction) ((uint8_t *)game_header->render + address); - user_tick = (BlitTickFunction) ((uint8_t *)game_header->tick + address); + if(game_header->magic == blit_game_magic) { - if(!init(address)) { - user_render = nullptr; - user_tick = nullptr; + persist.last_game_offset = address; - qspi_disable_memorymapped_mode(); - - return false; - } - - blit::render = user_render; - do_tick = user_tick; + // game possibly running, wait until it isn't + if(user_tick && !user_code_disabled) { + game_switch_requested = true; return true; } - // anything flashed at a non-zero offset should have a valid header - else if(address != 0) - return false; - } - - // old-style soft-reset to app with linked HAL - // left for compatibility/testing - - adc::stop(); - // Stop the audio - HAL_TIM_Base_Stop_IT(&htim6); - HAL_DAC_Stop(&hdac1, DAC_CHANNEL_2); + // avoid starting a game disabled (will break sound and the menu) + if(user_code_disabled) + blit_enable_user_code(); - // Stop system button timer - HAL_TIM_Base_Stop_IT(&htim2); - - // stop USB - USBD_Stop(&hUsbDeviceHS); + cached_file_in_tmp = false; + close_open_files(); - // Disable all the interrupts... just to be sure - HAL_NVIC_DisableIRQ(LTDC_IRQn); - HAL_NVIC_DisableIRQ(ADC_IRQn); - HAL_NVIC_DisableIRQ(ADC3_IRQn); - HAL_NVIC_DisableIRQ(DMA1_Stream0_IRQn); - HAL_NVIC_DisableIRQ(DMA1_Stream1_IRQn); - HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn); - HAL_NVIC_DisableIRQ(OTG_HS_IRQn); - HAL_NVIC_DisableIRQ(EXTI9_5_IRQn); - HAL_NVIC_DisableIRQ(TIM2_IRQn); + // load function pointers + auto init = (BlitInitFunction)((uint8_t *)game_header->init + address); - /* Disable I-Cache */ - SCB_DisableICache(); + // set these up early so that blit_user_code_running works in code called from init + user_render = (BlitRenderFunction) ((uint8_t *)game_header->render + address); + user_tick = (BlitTickFunction) ((uint8_t *)game_header->tick + address); - /* Disable D-Cache */ - SCB_DisableDCache(); + if(!init(address)) { + user_render = nullptr; + user_tick = nullptr; - /* Disable Systick interrupt */ - SysTick->CTRL = 0; + qspi_disable_memorymapped_mode(); - typedef void (*pFunction)(void); - /* Initialize user application's Stack Pointer & Jump to user application */ - auto JumpToApplication = (pFunction) (*(__IO uint32_t*) (EXTERNAL_LOAD_ADDRESS + 4)); - __set_MSP(*(__IO uint32_t*) EXTERNAL_LOAD_ADDRESS); - JumpToApplication(); + return false; + } - /* We should never get here as execution is now on user application */ - while(1) - { - } + blit::render = user_render; + do_tick = user_tick; + return true; + } - return true; + return false; } bool blit_user_code_running() { - // running fully linked code from ext flash - if(APPLICATION_VTOR == 0x90000000) - return true; - // loaded user-only game from flash return user_tick != nullptr; } @@ -789,12 +734,12 @@ RawMetadata *blit_get_running_game_metadata() { if(!blit_user_code_running()) return nullptr; - auto game_ptr = reinterpret_cast(0x90000000 + persist.last_game_offset); + auto game_ptr = reinterpret_cast(qspi_flash_address + persist.last_game_offset); auto header = reinterpret_cast(game_ptr); if(header->magic == blit_game_magic) { - auto end_ptr = game_ptr + (header->end - 0x90000000); + auto end_ptr = game_ptr + (header->end - qspi_flash_address); if(memcmp(end_ptr, "BLITMETA", 8) == 0) return reinterpret_cast(end_ptr + 10); } diff --git a/32blit-stm32/Src/CDCCommandStream.cpp b/32blit-stm32/Src/CDCCommandStream.cpp index 312d068aa..5573ecfdc 100644 --- a/32blit-stm32/Src/CDCCommandStream.cpp +++ b/32blit-stm32/Src/CDCCommandStream.cpp @@ -22,7 +22,7 @@ void CDCCommandStream::Init(void) void CDCCommandStream::AddCommandHandler(CDCCommandHandler::CDCFourCC uCommand, CDCCommandHandler *pCommandHandler) { - m_commandHandlers[uCommand] = pCommandHandler; + m_commandHandlers.emplace(uCommand, pCommandHandler); } @@ -73,6 +73,8 @@ void CDCCommandStream::Stream(void) uint8_t CDCCommandStream::Stream(uint8_t *data, uint32_t len) { + static const uint8_t header[4] = { '3', '2', 'B', 'L' }; + uint8_t *pScanPos = data; while(pScanPos < (data+len)) @@ -82,7 +84,7 @@ uint8_t CDCCommandStream::Stream(uint8_t *data, uint32_t len) bool bHeaderFound = false; while ((!bHeaderFound) && (pScanPos < (data+len))) { - if(*pScanPos == m_header[m_uHeaderScanPos]) + if(*pScanPos == header[m_uHeaderScanPos]) { if(m_uHeaderScanPos == 3) { @@ -141,7 +143,9 @@ uint8_t CDCCommandStream::Stream(uint8_t *data, uint32_t len) m_uRetryCount = 0; m_uDispatchTime = HAL_GetTick(); - m_pCurrentCommandHandler = m_commandHandlers[uCommand]; + auto handler = m_commandHandlers.find(uCommand); + m_pCurrentCommandHandler = handler == m_commandHandlers.end() ? nullptr : handler->second; + if(m_pCurrentCommandHandler) { if(m_pCurrentCommandHandler->StreamInit(uCommand)) { diff --git a/32blit-stm32/Src/CDCResetHandler.cpp b/32blit-stm32/Src/CDCResetHandler.cpp index 9f9f74dce..4d564f8c4 100644 --- a/32blit-stm32/Src/CDCResetHandler.cpp +++ b/32blit-stm32/Src/CDCResetHandler.cpp @@ -10,14 +10,10 @@ bool CDCResetHandler::StreamInit(CDCFourCC uCommand) { -#if EXTERNAL_LOAD_ADDRESS == 0x90000000 if(uCommand == CDCCommandHandler::CDCFourCCMake<'S', 'W', 'I', 'T'>::value || blit_user_code_running()) - blit_switch_execution(0, false); + blit_switch_execution(0, false); else NVIC_SystemReset(); -#else - blit_switch_execution(0); -#endif return false; } diff --git a/32blit-stm32/Src/adc.cpp b/32blit-stm32/Src/adc.cpp index 32a4826cb..090beb3e0 100644 --- a/32blit-stm32/Src/adc.cpp +++ b/32blit-stm32/Src/adc.cpp @@ -36,13 +36,6 @@ namespace adc { HAL_ADC_Start_DMA(&hadc3, (uint32_t *)adc3data, ADC_BUFFER_SIZE); } - // this is only used by the old exe switching code - void stop() { - // Stop the ADC DMA - HAL_ADC_Stop_DMA(&hadc1); - HAL_ADC_Stop_DMA(&hadc3); - } - uint16_t get_value(Value v) { switch(v) { case Value::joystick_x: diff --git a/32blit-stm32/Src/display.cpp b/32blit-stm32/Src/display.cpp index 7ce9d622d..8902c761b 100644 --- a/32blit-stm32/Src/display.cpp +++ b/32blit-stm32/Src/display.cpp @@ -11,6 +11,20 @@ extern char __ltdc_start, __ltdc_end; extern char __fb_start, __fb_end; +namespace display { + static void screen_init(); + static void ltdc_init(); + + static void flip(const Surface &source); + + static uint32_t get_dma2d_count(); + + static void dma2d_lores_flip_step2(); + static void dma2d_lores_flip_step3(); + static void dma2d_lores_flip_step4(); + + static void update_ltdc_for_mode(); +} void LTDC_IRQHandler() { // check that interrupt triggered was line end event @@ -53,15 +67,13 @@ void DMA2D_IRQHandler(void){ } namespace display { - void update_ltdc_for_mode(); - __IO uint32_t dma2d_step_count = 0; static Pen palette[256]; - // lo and hi res screen back buffers - static const blit::SurfaceTemplate __fb_hires{(uint8_t *)&__fb_start, blit::Size(320, 240), blit::PixelFormat::RGB, nullptr}; - static const blit::SurfaceTemplate __fb_hires_pal{(uint8_t *)&__fb_start, blit::Size(320, 240), blit::PixelFormat::P, palette}; - static const blit::SurfaceTemplate __fb_lores{(uint8_t *)&__fb_start, blit::Size(160, 120), blit::PixelFormat::RGB, nullptr}; + + // lo and hi res screen size + static const blit::Size hires_screen_size(320, 240); + static const blit::Size lores_screen_size(160, 120); static SurfaceInfo cur_surf_info; // used to pass screen info back through API @@ -106,23 +118,15 @@ namespace display { } SurfaceInfo &set_screen_mode(ScreenMode new_mode) { - requested_mode = new_mode; - switch(new_mode) { - case ScreenMode::lores: - cur_surf_info = __fb_lores; - break; - case ScreenMode::hires: - cur_surf_info = __fb_hires; - break; - case ScreenMode::hires_palette: - cur_surf_info = __fb_hires_pal; - break; - } + SurfaceTemplate temp{nullptr, {0, 0}, new_mode == ScreenMode::hires_palette ? PixelFormat::P : PixelFormat::RGB}; - screen = Surface(cur_surf_info.data, cur_surf_info.format, cur_surf_info.bounds); - screen.palette = cur_surf_info.palette; + // won't fail for the modes used here + set_screen_mode_format(new_mode, temp); - requested_format = screen.format; + cur_surf_info.data = temp.data; + cur_surf_info.bounds = temp.bounds; + cur_surf_info.format = temp.format; + cur_surf_info.palette = temp.palette; return cur_surf_info; } @@ -138,11 +142,11 @@ namespace display { switch(new_mode) { case ScreenMode::lores: - new_surf_template.bounds = __fb_lores.bounds; + new_surf_template.bounds = lores_screen_size; break; case ScreenMode::hires: case ScreenMode::hires_palette: - new_surf_template.bounds = __fb_hires.bounds; + new_surf_template.bounds = hires_screen_size; break; } @@ -169,7 +173,7 @@ namespace display { return true; } - void dma2d_hires_flip(const Surface &source) { + static void dma2d_hires_flip(const Surface &source) { SCB_CleanInvalidateDCache_by_Addr((uint32_t *)(source.data), 320 * 240 * 3); // set the transform type (clear bits 17..16 of control register) MODIFY_REG(DMA2D->CR, DMA2D_CR_MODE, LL_DMA2D_MODE_M2M_PFC); @@ -198,7 +202,7 @@ namespace display { DMA2D->CR |= DMA2D_CR_START; } - void dma2d_hires_pal_flip(const Surface &source) { + static void dma2d_hires_pal_flip(const Surface &source) { // copy RGBA at quarter width // work as 32bit type to save some bandwidth SCB_CleanInvalidateDCache_by_Addr((uint32_t *)(source.data), 320 * 240 * 1); @@ -234,7 +238,7 @@ namespace display { } } - void dma2d_lores_flip(const Surface &source) { + static void dma2d_lores_flip(const Surface &source) { SCB_CleanInvalidateDCache_by_Addr((uint32_t *)(source.data), 160 * 120 * 3); // palette update @@ -280,7 +284,7 @@ namespace display { DMA2D->CR |= DMA2D_CR_START; } - void dma2d_lores_flip_step2(void){ + static void dma2d_lores_flip_step2(void){ //Step 2. // set the transform type (clear bits 17..16 of control register) MODIFY_REG(DMA2D->CR, DMA2D_CR_MODE, LL_DMA2D_MODE_M2M); @@ -303,7 +307,7 @@ namespace display { DMA2D->CR |= DMA2D_CR_START; } - void dma2d_lores_flip_step3(void){ + static void dma2d_lores_flip_step3(void){ //step 3. // set the transform type (clear bits 17..16 of control register) MODIFY_REG(DMA2D->CR, DMA2D_CR_MODE, LL_DMA2D_MODE_M2M); @@ -326,7 +330,7 @@ namespace display { DMA2D->CR |= DMA2D_CR_START; } - void dma2d_lores_flip_step4(void){ + static void dma2d_lores_flip_step4(void){ // set the transform type (clear bits 17..16 of control register) MODIFY_REG(DMA2D->CR, DMA2D_CR_MODE, LL_DMA2D_MODE_M2M); // set source pixel format (clear bits 3..0 of foreground format register) @@ -348,7 +352,7 @@ namespace display { DMA2D->CR |= DMA2D_CR_START; } - void flip(const Surface &source) { + static void flip(const Surface &source) { // switch colour mode if needed if(need_ltdc_mode_update) { update_ltdc_for_mode(); @@ -365,14 +369,14 @@ namespace display { } } - void screen_init() { + static void screen_init() { ST7272A_RESET(); // st7272a_set_bgr(); } // configure ltdc peripheral setting up the clocks, pin states, panel // parameters, and layers - void ltdc_init() { + static void ltdc_init() { // enable ltdc clock __HAL_RCC_LTDC_CLK_ENABLE(); @@ -421,7 +425,7 @@ namespace display { LTDC->GCR |= LTDC_GCR_LTDCEN; } - void update_ltdc_for_mode() { + static void update_ltdc_for_mode() { // hires palette is special if(mode != ScreenMode::lores && format == PixelFormat::P) { LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT_L8; @@ -438,7 +442,7 @@ namespace display { LTDC->SRCR = LTDC_SRCR_IMR; } - uint32_t get_dma2d_count(void){ + static uint32_t get_dma2d_count(void){ return dma2d_step_count; } } diff --git a/32blit-stm32/Src/fatfs.c b/32blit-stm32/Src/fatfs.c deleted file mode 100644 index a9b9715fa..000000000 --- a/32blit-stm32/Src/fatfs.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - ****************************************************************************** - * @file fatfs.c - * @brief Code for fatfs applications - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "fatfs.h" - -uint8_t retUSER; /* Return value for USER */ -char USERPath[4]; /* USER logical drive path */ -FATFS USERFatFS; /* File system object for USER logical drive */ -FIL USERFile; /* File object for USER */ - -/* USER CODE BEGIN Variables */ - -/* USER CODE END Variables */ - -void MX_FATFS_Init(void) -{ - /*## FatFS: Link the USER driver ###########################*/ - retUSER = FATFS_LinkDriver(&USER_Driver, USERPath); - - /* USER CODE BEGIN Init */ - /* additional user code for init */ - /* USER CODE END Init */ -} - -/** - * @brief Gets Time from RTC - * @param None - * @retval Time in DWORD - */ -DWORD get_fattime(void) -{ - /* USER CODE BEGIN get_fattime */ - return 0; - /* USER CODE END get_fattime */ -} - -/* USER CODE BEGIN Application */ - -/* USER CODE END Application */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/32blit-stm32/Src/fatfs.cpp b/32blit-stm32/Src/fatfs.cpp new file mode 100644 index 000000000..979f05639 --- /dev/null +++ b/32blit-stm32/Src/fatfs.cpp @@ -0,0 +1,29 @@ + +#include "ff.h" +#include "diskio.h" + +extern "C" { +#include "fatfs_sd.h" +} + +DSTATUS disk_initialize(BYTE pdrv) { + return SD_disk_initialize(pdrv); +} + +DSTATUS disk_status(BYTE pdrv) { + return SD_disk_status(pdrv); +} + +DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) { + return SD_disk_read(pdrv, buff, sector, count); +} + +#if !FF_FS_READONLY +DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) { + return SD_disk_write(pdrv, buff, sector, count); +} +#endif + +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) { + return SD_disk_ioctl(pdrv, cmd, buff); +} diff --git a/32blit-stm32/Src/fatfs_sd.c b/32blit-stm32/Src/fatfs_sd.c index aa071a5d7..87a25fff0 100644 --- a/32blit-stm32/Src/fatfs_sd.c +++ b/32blit-stm32/Src/fatfs_sd.c @@ -4,7 +4,9 @@ #include "stm32h7xx_hal.h" #include #include -#include "ff_gen_drv.h" + +#include "ff.h" +#include "diskio.h" #include "fatfs_sd.h" static volatile DSTATUS Stat = STA_NOINIT; /* Disk Status */ @@ -231,7 +233,7 @@ static bool SD_RxDataBlock(BYTE *buff, uint16_t len) } /* transmit data block */ -#if _USE_WRITE == 1 +#if FF_FS_READONLY == 0 static bool SD_TxDataBlock(const uint8_t *buff, BYTE token) { uint8_t resp; @@ -294,7 +296,7 @@ static bool SD_TxDataBlock(const uint8_t *buff, BYTE token) return FALSE; } -#endif /* _USE_WRITE */ +#endif /* FF_FS_READONLY */ /* transmit command */ static BYTE SD_SendCmd(BYTE cmd, uint32_t arg) @@ -484,7 +486,7 @@ DRESULT SD_disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) } /* write sector */ -#if _USE_WRITE == 1 +#if FF_FS_READONLY == 0 DRESULT SD_disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* pdrv should be 0 */ @@ -537,7 +539,7 @@ DRESULT SD_disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) return count ? RES_ERROR : RES_OK; } -#endif /* _USE_WRITE */ +#endif /* FF_FS_READONLY */ /* ioctl */ DRESULT SD_disk_ioctl(BYTE drv, BYTE ctrl, void *buff) diff --git a/32blit-stm32/Src/file.cpp b/32blit-stm32/Src/file.cpp index ee3a6fa23..98ae55746 100644 --- a/32blit-stm32/Src/file.cpp +++ b/32blit-stm32/Src/file.cpp @@ -3,7 +3,7 @@ #include #include -#include "fatfs.h" +#include "ff.h" #include "file.hpp" #include "32blit.h" @@ -167,7 +167,8 @@ bool remove_file(const std::string &path) { static char save_path[32]; // max game title length is 24 + ".blit/" + "/" const char *get_save_path() { - std::string app_name; + const char *app_name; + char buf[10]; if(!directory_exists(".blit")) create_directory(".blit"); @@ -181,16 +182,16 @@ const char *get_save_path() { app_name = meta->title; else { // fallback to offset - app_name = std::to_string(persist.last_game_offset); + snprintf(buf, 10, "%li", persist.last_game_offset); + app_name = buf; } } - snprintf(save_path, sizeof(save_path), ".blit/%s/", app_name.c_str()); + snprintf(save_path, sizeof(save_path), ".blit/%s/", app_name); // make sure it exists if(!directory_exists(save_path)) create_directory(save_path); - return save_path; } diff --git a/32blit-stm32/Src/gpio.cpp b/32blit-stm32/Src/gpio.cpp index c284b771d..73f27854a 100644 --- a/32blit-stm32/Src/gpio.cpp +++ b/32blit-stm32/Src/gpio.cpp @@ -7,22 +7,18 @@ namespace gpio { HAL_GPIO_Init(port, &gpio); } - // initialises all of the pins of the MCU into the correct - // configuration for 32blit + // initialises all of the pins of the MCU into the correct + // configuration for 32blit void init() { - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); + // enable clocks + RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN | RCC_AHB4ENR_GPIOBEN | RCC_AHB4ENR_GPIOCEN | RCC_AHB4ENR_GPIODEN | RCC_AHB4ENR_GPIOEEN | RCC_AHB4ENR_GPIOHEN; + (void)RCC->AHB4ENR; // read back // set initial output states where needed - HAL_GPIO_WritePin(AMP_SHUTDOWN_GPIO_Port, AMP_SHUTDOWN_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(GPIOA, LCD_CS_Pin|LCD_RESET_Pin|SD_SPI1_CS_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(USB_SWAP_GPIO_Port, USB_SWAP_Pin, GPIO_PIN_RESET); + write(AMP_SHUTDOWN_GPIO_Port, AMP_SHUTDOWN_Pin, true); + write(GPIOA, LCD_CS_Pin|LCD_RESET_Pin|SD_SPI1_CS_Pin, false); + write(USB_SWAP_GPIO_Port, USB_SWAP_Pin, false); // usb otg init_pin(GPIOB, GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF12_OTG2_FS); @@ -33,13 +29,10 @@ namespace gpio { // usb "swap" pin? init_pin(GPIOD, USB_SWAP_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL); -#if (INITIALISE_QSPI==1) -// Guard against user code changing QSPI pin state set by firmware // qspi init_pin(GPIOB, GPIO_PIN_2, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_AF9_QUADSPI); init_pin(GPIOE, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_AF10_QUADSPI); init_pin(GPIOC, GPIO_PIN_11, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_AF9_QUADSPI); -#endif // spi1 init_pin(GPIOA, SD_SPI1_MOSI_Pin, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_AF5_SPI1); @@ -77,7 +70,7 @@ namespace gpio { // battery sense init_pin(GPIOC, BATTERY_SENSE_Pin, GPIO_MODE_ANALOG, GPIO_NOPULL); // battery sense - + // "gpio" pin on extension header init_pin(GPIOC, EXTENSION_GPIO_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL); // left digital @@ -148,8 +141,8 @@ namespace gpio { init_pin(LED_CHG_GREEN_Port, LED_CHG_GREEN_Pin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH); init_pin(LED_CHG_BLUE_Port, LED_CHG_BLUE_Pin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_VERY_HIGH); - HAL_GPIO_WritePin(LED_CHG_RED_Port, LED_CHG_RED_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(LED_CHG_GREEN_Port, LED_CHG_GREEN_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(LED_CHG_BLUE_Port, LED_CHG_BLUE_Pin, GPIO_PIN_SET); + write(LED_CHG_RED_Port, LED_CHG_RED_Pin, true); + write(LED_CHG_GREEN_Port, LED_CHG_GREEN_Pin, true); + write(LED_CHG_BLUE_Port, LED_CHG_BLUE_Pin, true); } } diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c index 36a2cb4ca..fe5de680f 100644 --- a/32blit-stm32/Src/main.c +++ b/32blit-stm32/Src/main.c @@ -21,7 +21,6 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "dma.h" -#include "fatfs.h" #include "hrtim.h" #include "i2c.h" #include "jpeg.h" @@ -124,7 +123,7 @@ int main(void) gpio::init(); sound::init(); - is_beta_unit = HAL_GPIO_ReadPin(VERSION_GPIO_Port, VERSION_Pin); + is_beta_unit = gpio::read(VERSION_GPIO_Port, VERSION_Pin); //MX_GPIO_Init(); @@ -135,9 +134,8 @@ int main(void) //MX_DAC1_Init(); MX_HRTIM_Init(); MX_I2C4_Init(); -#if (INITIALISE_QSPI==1) MX_QUADSPI_Init(); -#endif + adc::init(); //MX_USB_OTG_HS_USB_Init(); @@ -146,7 +144,6 @@ int main(void) //MX_TIM6_Init(); MX_TIM15_Init(); //MX_TIM16_Init(); - MX_FATFS_Init(); MX_RNG_Init(); MX_USB_DEVICE_Init(); MX_JPEG_Init(); @@ -158,9 +155,7 @@ int main(void) //NVIC_SetPriority(SysTick_IRQn, 0x0); -#if (INITIALISE_QSPI==1) qspi_init(); -#endif blit_init(); diff --git a/32blit-stm32/Src/sound.cpp b/32blit-stm32/Src/sound.cpp index 099ae0311..306907e49 100644 --- a/32blit-stm32/Src/sound.cpp +++ b/32blit-stm32/Src/sound.cpp @@ -20,7 +20,7 @@ void TIM6_DAC_IRQHandler(void) { bool enable_amp = sound::enabled && is_audio_playing(); if(enable_amp != was_amp_enabled) { - HAL_GPIO_WritePin(AMP_SHUTDOWN_GPIO_Port, AMP_SHUTDOWN_Pin, enable_amp ? GPIO_PIN_SET : GPIO_PIN_RESET); + gpio::write(AMP_SHUTDOWN_GPIO_Port, AMP_SHUTDOWN_Pin, enable_amp); was_amp_enabled = enable_amp; } diff --git a/32blit-stm32/Src/stm32h7xx_it.c b/32blit-stm32/Src/stm32h7xx_it.c index 5b28d29d2..ab99894a0 100644 --- a/32blit-stm32/Src/stm32h7xx_it.c +++ b/32blit-stm32/Src/stm32h7xx_it.c @@ -21,7 +21,6 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32h7xx_it.h" -#include "fatfs.h" #include "gpio_defs.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -40,7 +39,7 @@ extern void blit_reset_with_error(); /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ - + /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ @@ -79,7 +78,7 @@ extern I2C_HandleTypeDef hi2c4; /* USER CODE END EV */ /******************************************************************************/ -/* Cortex Processor Interruption and Exception Handlers */ +/* Cortex Processor Interruption and Exception Handlers */ /******************************************************************************/ /** * @brief This function handles Non maskable interrupt. diff --git a/32blit-stm32/Src/system_stm32h7xx.c b/32blit-stm32/Src/system_stm32h7xx.c index be0a38eff..f17b693c5 100644 --- a/32blit-stm32/Src/system_stm32h7xx.c +++ b/32blit-stm32/Src/system_stm32h7xx.c @@ -237,7 +237,7 @@ void SystemInit (void) #ifdef VECT_TAB_SRAM SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM */ #else - SCB->VTOR = APPLICATION_VTOR | VECT_TAB_OFFSET; /* Vector Table Relocation set by APPLICATION_VTOR */ + SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif #endif /*DUAL_CORE && CORE_CM4*/ diff --git a/32blit-stm32/Src/user_diskio.c b/32blit-stm32/Src/user_diskio.c deleted file mode 100644 index 9fbe6a6a9..000000000 --- a/32blit-stm32/Src/user_diskio.c +++ /dev/null @@ -1,167 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file user_diskio.c - * @brief This file includes a diskio driver skeleton to be completed by the user. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - /* USER CODE END Header */ - -#ifdef USE_OBSOLETE_USER_CODE_SECTION_0 -/* - * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0) - * To be suppressed in the future. - * Kept to ensure backward compatibility with previous CubeMx versions when - * migrating projects. - * User code previously added there should be copied in the new user sections before - * the section contents can be deleted. - */ -/* USER CODE BEGIN 0 */ -/* USER CODE END 0 */ -#endif - -/* USER CODE BEGIN DECL */ - -/* Includes ------------------------------------------------------------------*/ -#include -#include "ff_gen_drv.h" -#include "fatfs_sd.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -/* Disk status */ -static volatile DSTATUS Stat = STA_NOINIT; - -/* USER CODE END DECL */ - -/* Private function prototypes -----------------------------------------------*/ -DSTATUS USER_initialize (BYTE pdrv); -DSTATUS USER_status (BYTE pdrv); -DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count); -#if _USE_WRITE == 1 - DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count); -#endif /* _USE_WRITE == 1 */ -#if _USE_IOCTL == 1 - DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff); -#endif /* _USE_IOCTL == 1 */ - -Diskio_drvTypeDef USER_Driver = -{ - USER_initialize, - USER_status, - USER_read, -#if _USE_WRITE - USER_write, -#endif /* _USE_WRITE == 1 */ -#if _USE_IOCTL == 1 - USER_ioctl, -#endif /* _USE_IOCTL == 1 */ -}; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief Initializes a Drive - * @param pdrv: Physical drive number (0..) - * @retval DSTATUS: Operation status - */ -DSTATUS USER_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - /* USER CODE BEGIN INIT */ - return SD_disk_initialize(pdrv); - /* USER CODE END INIT */ -} - -/** - * @brief Gets Disk Status - * @param pdrv: Physical drive number (0..) - * @retval DSTATUS: Operation status - */ -DSTATUS USER_status ( - BYTE pdrv /* Physical drive number to identify the drive */ -) -{ - /* USER CODE BEGIN STATUS */ - return SD_disk_status(pdrv); - /* USER CODE END STATUS */ -} - -/** - * @brief Reads Sector(s) - * @param pdrv: Physical drive number (0..) - * @param *buff: Data buffer to store read data - * @param sector: Sector address (LBA) - * @param count: Number of sectors to read (1..128) - * @retval DRESULT: Operation result - */ -DRESULT USER_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Sector address in LBA */ - UINT count /* Number of sectors to read */ -) -{ - /* USER CODE BEGIN READ */ - return SD_disk_read(pdrv, buff, sector, count); - /* USER CODE END READ */ -} - -/** - * @brief Writes Sector(s) - * @param pdrv: Physical drive number (0..) - * @param *buff: Data to be written - * @param sector: Sector address (LBA) - * @param count: Number of sectors to write (1..128) - * @retval DRESULT: Operation result - */ -#if _USE_WRITE == 1 -DRESULT USER_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Sector address in LBA */ - UINT count /* Number of sectors to write */ -) -{ - /* USER CODE BEGIN WRITE */ - /* USER CODE HERE */ - return SD_disk_write(pdrv, buff, sector, count); - /* USER CODE END WRITE */ -} -#endif /* _USE_WRITE == 1 */ - -/** - * @brief I/O control operation - * @param pdrv: Physical drive number (0..) - * @param cmd: Control code - * @param *buff: Buffer to send/receive control data - * @retval DRESULT: Operation result - */ -#if _USE_IOCTL == 1 -DRESULT USER_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - /* USER CODE BEGIN IOCTL */ - return SD_disk_ioctl(pdrv, cmd, buff); - /* USER CODE END IOCTL */ -} -#endif /* _USE_IOCTL == 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/32blit.toolchain b/32blit.toolchain index 3b0f4faa9..88c76f32a 100644 --- a/32blit.toolchain +++ b/32blit.toolchain @@ -18,16 +18,8 @@ if (MCU_FLOAT_ABI STREQUAL hard) set(MCU_FLAGS "${MCU_FLAGS} -mfpu=${MCU_FPU}") endif () -set(APPLICATION_VTOR 0x08000000) -set(EXTERNAL_LOAD_ADDRESS 0x90000000) -set(INITIALISE_QSPI 1) set(CDC_FIFO_BUFFERS 64) -set(APPLICATION_VTOR_EXT 0x90000000) -set(EXTERNAL_LOAD_ADDRESS_EXT 0x08000000) -set(INITIALISE_QSPI_EXT 0) -set(CDC_FIFO_BUFFERS_EXT 4) - set(COMMON_FLAGS "${MCU_FLAGS} -fsingle-precision-constant -Wall -fdata-sections -ffunction-sections -Wattributes -Wdouble-promotion -Werror=double-promotion -mno-pic-data-is-text-relative -mno-single-pic-base") set(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS}") diff --git a/32blit/graphics/surface.cpp b/32blit/graphics/surface.cpp index 8f21aab2c..4c0c56fe6 100644 --- a/32blit/graphics/surface.cpp +++ b/32blit/graphics/surface.cpp @@ -49,7 +49,36 @@ namespace blit { #pragma pack(pop) Surface::Surface(uint8_t *data, const PixelFormat &format, const Size &bounds) : data(data), bounds(bounds), format(format) { - init(); + clip = Rect(0, 0, bounds.w, bounds.h); + + rows = bounds.h / 8; + cols = bounds.w / 8; + + pixel_stride = pixel_format_stride[static_cast(format)]; + row_stride = pixel_stride * bounds.w; + + switch (format) { + case PixelFormat::RGBA: { + pbf = RGBA_RGBA; + bbf = RGBA_RGBA; + }break; + case PixelFormat::RGB: { + pbf = RGBA_RGB; + bbf = RGBA_RGB; + }break; + case PixelFormat::P: { + pbf = P_P; + bbf = P_P; + }break; + case PixelFormat::M: { + pbf = M_M; + bbf = M_M; + }break; + case PixelFormat::RGB565: { + pbf = RGBA_RGB565; + bbf = RGBA_RGB565; + }break; + } } /** @@ -215,39 +244,6 @@ namespace blit { return true; } - void Surface::init() { - clip = Rect(0, 0, bounds.w, bounds.h); - - rows = bounds.h / 8; - cols = bounds.w / 8; - - pixel_stride = pixel_format_stride[static_cast(format)]; - row_stride = pixel_stride * bounds.w; - - switch (format) { - case PixelFormat::RGBA: { - pbf = RGBA_RGBA; - bbf = RGBA_RGBA; - }break; - case PixelFormat::RGB: { - pbf = RGBA_RGB; - bbf = RGBA_RGB; - }break; - case PixelFormat::P: { - pbf = P_P; - bbf = P_P; - }break; - case PixelFormat::M: { - pbf = M_M; - bbf = M_M; - }break; - case PixelFormat::RGB565: { - pbf = RGBA_RGB565; - bbf = RGBA_RGB565; - }break; - } - } - /** * Generate mipmaps for surface * diff --git a/32blit/graphics/surface.hpp b/32blit/graphics/surface.hpp index 88ec7fb13..d190e1fa9 100644 --- a/32blit/graphics/surface.hpp +++ b/32blit/graphics/surface.hpp @@ -134,8 +134,6 @@ namespace blit { uint16_t rows, cols; private: - void init(); - static Surface *load_from_bmp(File &file, uint8_t *data, size_t data_size); static Surface *load_from_packed(File &file, uint8_t *data, size_t data_size, bool readonly); diff --git a/firmware/firmware.cpp b/firmware/firmware.cpp index 9b15017e4..a28fea4be 100644 --- a/firmware/firmware.cpp +++ b/firmware/firmware.cpp @@ -10,18 +10,12 @@ #include "executable.hpp" #include "dialog.hpp" #include "power.hpp" +#include "quadspi.hpp" #include "engine/api_private.hpp" using namespace blit; -constexpr uint32_t qspi_flash_sector_size = 64 * 1024; -constexpr uint32_t qspi_flash_size = 32768 * 1024; -constexpr uint32_t qspi_flash_address = 0x90000000; - -// resevered space for temp/cached files -constexpr uint32_t qspi_tmp_reserved = 4 * 1024 * 1024; - extern CDCCommandStream g_commandStream; FlashLoader flashLoader; @@ -112,52 +106,54 @@ static bool parse_flash_metadata(uint32_t offset, GameInfo &info) { } static bool parse_file_metadata(FIL &fh, GameInfo &info) { - BlitGameHeader header; UINT bytes_read; - bool result = false; - f_lseek(&fh, 0); - f_read(&fh, &header, sizeof(header), &bytes_read); + uint8_t buf[10]; // skip relocation data - int off = 0; - if(header.magic == 0x4F4C4552 /* RELO */) { - f_lseek(&fh, 4); - uint32_t num_relocs; - f_read(&fh, (void *)&num_relocs, 4, &bytes_read); + f_lseek(&fh, 0); + f_read(&fh, buf, 4, &bytes_read); - off = num_relocs * 4 + 8; - f_lseek(&fh, off); + if(memcmp(buf, "RELO", 4) != 0) + return false; - // re-read header - f_read(&fh, &header, sizeof(header), &bytes_read); - } + uint32_t num_relocs; + f_read(&fh, (void *)&num_relocs, 4, &bytes_read); - if(header.magic == blit_game_magic) { - uint8_t buf[10]; - f_lseek(&fh, (header.end - qspi_flash_address) + off); - f_read(&fh, buf, 10, &bytes_read); + int relocs_size = num_relocs * 4 + 8; + f_lseek(&fh, relocs_size); + + // read header + BlitGameHeader header; + f_read(&fh, &header, sizeof(header), &bytes_read); - if(bytes_read == 10 && memcmp(buf, "BLITMETA", 8) == 0) { - // don't bother reading the whole thing since we don't want the images - RawMetadata raw_meta; - f_read(&fh, &raw_meta, sizeof(RawMetadata), &bytes_read); + if(header.magic != blit_game_magic) + return false; - info.size += *reinterpret_cast(buf + 8) + 10; - info.checksum = raw_meta.crc32; - memcpy(info.title, raw_meta.title, sizeof(info.title)); - memcpy(info.author, raw_meta.author, sizeof(info.author)); + bool result = false; - result = true; - } + // get metadata + f_lseek(&fh, (header.end - qspi_flash_address) + relocs_size); + f_read(&fh, buf, 10, &bytes_read); - // read category - f_read(&fh, buf, 8, &bytes_read); - if(bytes_read == 8 && memcmp(buf, "BLITTYPE", 8) == 0) { - RawTypeMetadata type_meta; - f_read(&fh, &type_meta, sizeof(RawTypeMetadata), &bytes_read); - memcpy(info.category, type_meta.category, sizeof(info.category)); - } + if(bytes_read == 10 && memcmp(buf, "BLITMETA", 8) == 0) { + // don't bother reading the whole thing since we don't want the images + RawMetadata raw_meta; + f_read(&fh, &raw_meta, sizeof(RawMetadata), &bytes_read); + + info.size += *reinterpret_cast(buf + 8) + 10; + info.checksum = raw_meta.crc32; + memcpy(info.title, raw_meta.title, sizeof(info.title)); + memcpy(info.author, raw_meta.author, sizeof(info.author)); + result = true; + } + + // read category + f_read(&fh, buf, 8, &bytes_read); + if(bytes_read == 8 && memcmp(buf, "BLITTYPE", 8) == 0) { + RawTypeMetadata type_meta; + f_read(&fh, &type_meta, sizeof(RawTypeMetadata), &bytes_read); + memcpy(info.category, type_meta.category, sizeof(info.category)); } return result; @@ -345,29 +341,24 @@ static uint32_t flash_from_sd_to_qspi_flash(FIL &file, uint32_t flash_offset) { f_read(&file, buf, 4, &bytes_read); std::vector relocation_offsets; size_t cur_reloc = 0; - bool has_relocs = false; - if(memcmp(buf, "RELO", 4) == 0) { - uint32_t num_relocs; - f_read(&file, (void *)&num_relocs, 4, &bytes_read); - relocation_offsets.reserve(num_relocs); + if(memcmp(buf, "RELO", 4) != 0) + return 0xFFFFFFFF; - for(auto i = 0u; i < num_relocs; i++) { - uint32_t reloc_offset; - f_read(&file, (void *)&reloc_offset, 4, &bytes_read); + uint32_t num_relocs; + f_read(&file, (void *)&num_relocs, 4, &bytes_read); + relocation_offsets.reserve(num_relocs); - relocation_offsets.push_back(reloc_offset - qspi_flash_address); - } + for(auto i = 0u; i < num_relocs; i++) { + uint32_t reloc_offset; + f_read(&file, (void *)&reloc_offset, 4, &bytes_read); - bytes_total -= num_relocs * 4 + 8; // size of relocation data - has_relocs = true; - } else { - f_lseek(&file, 0); + relocation_offsets.push_back(reloc_offset - qspi_flash_address); } - if(!has_relocs) - flash_offset = 0; - else if(flash_offset == 0xFFFFFFFF) + bytes_total -= num_relocs * 4 + 8; // size of relocation data + + if(flash_offset == 0xFFFFFFFF) flash_offset = get_flash_offset_for_file(bytes_total); // erase the sectors needed to write the image diff --git a/firmware/firmware.hpp b/firmware/firmware.hpp index f617a32c7..36f3e994c 100644 --- a/firmware/firmware.hpp +++ b/firmware/firmware.hpp @@ -1,7 +1,7 @@ #include "32blit.h" #include "32blit.hpp" #include "CDCCommandHandler.h" -#include "fatfs.h" +#include "ff.h" #include "persistence.h" #define BUFFER_SIZE (256)