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)