Skip to content

Commit

Permalink
First working version with MSC, memcard simulation and sync
Browse files Browse the repository at this point in the history
  • Loading branch information
dangiu committed May 10, 2022
1 parent e0fcfd7 commit 507555e
Show file tree
Hide file tree
Showing 18 changed files with 17,810 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tinyusb"]
path = tinyusb
url = https://github.com/hathach/tinyusb.git
8,195 changes: 8,195 additions & 0 deletions inc/freepsxboot_raw.h

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions inc/lfs_disk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __LFS_DISK_H__
#define __LFS_DISK_H__

#include <stdint.h>
#include "lfs.h"
#include "lfs_flash_handler.h"

#define LFS_BLOCK_COUNT 70
#define LFS_BLOCK_SIZE 4096

#define MEMCARD_FILE_NAME "memcard.mcr" // name of memcard file inside system
#define MEMCARD_FILE_CONTENT_SIZE 131072 // size of memcard file content in bytes (128KB)

/* LittleFS filesystem configuration */
extern const struct lfs_config LFS_CFG;

#endif
11 changes: 11 additions & 0 deletions inc/lfs_flash_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __LFS_FLASH_HANDLER_H__
#define __LFS_FLASH_HANDLER_H__

#include "lfs.h"

int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
int lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block);
int lfs_flash_sync(const struct lfs_config *c);

#endif
8,194 changes: 8,194 additions & 0 deletions inc/mc_raw.h

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions inc/memcard_simulator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef __MEMCARD_SIMULATOR_H__
#define __MEMCARD_SIMULATOR_H__

int simulate_memory_card();

#endif
34 changes: 34 additions & 0 deletions inc/memory_card.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef __MEMORY_CARD_H
#define __MEMORY_CARD_H

#include <stdint.h>
#include <stdbool.h>

#define MC_SEC_SIZE 128 // size of single sector in bytes
#define MC_SIZE MC_SEC_SIZE * 1024 // size of memory card in bytes
#define MC_MAX_SEC 0x3ff
#define MC_FLAG_BYTE_DEF 0x08 // bit 3 set = new memory card inserted

#define MC_ID1 0x5A
#define MC_ID2 0x5D
#define MC_ACK1 0x5C
#define MC_ACK2 0x5D

#define MC_GOOD 0x47
#define MC_BAD_SEC 0xFF
#define MC_BAD_CHK 0x4E

typedef struct {
uint8_t flag_byte;
uint8_t data[MC_SIZE];
} MemoryCard;

uint32_t memory_card_init(MemoryCard* mc);
bool memory_card_is_sector_valid(MemoryCard* mc, uint32_t sector);
//uint32_t memory_card_read_sector(MemoryCard* mc, uint32_t sector, uint8_t* buffer);
//uint32_t memory_card_write_sector(MemoryCard* mc, uint32_t sector, uint8_t* buffer);
uint8_t* memory_card_get_sector_ptr(MemoryCard* mc, uint32_t sector);
uint32_t memory_card_sync(MemoryCard* mc);
uint32_t memory_card_reset_seen_flag(MemoryCard* mc);

#endif
25 changes: 25 additions & 0 deletions inc/ram_disk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef __RAM_DISK_H__
#define __RAM_DISK_H__

#include <stdint.h>
#include "diskio.h"

#define VOLUME_LABEL "Pico MC"

#define DISK_BLOCK_NUM 353 // results in 128KB ram disk (some blocks are lost due to FAT12 overhead)
#define DISK_BLOCK_SIZE 512
#define SECTOR_NUM DISK_BLOCK_NUM
#define SECTOR_SIZE DISK_BLOCK_SIZE

/* FatFS Functions */
uint32_t RAM_disk_status();
uint32_t RAM_disk_initialize();
uint32_t RAM_disk_deinitialize();
uint32_t RAM_disk_read(uint8_t* buff, uint32_t sector, uint32_t count);
uint32_t RAM_disk_write(const uint8_t* buff, uint32_t sector, uint32_t count);
uint32_t RAM_disk_ioctl(uint8_t cmd, void* buff);

uint32_t RAM_disk_import_lfs_memcard();
uint32_t RAM_disk_export_lfs_memcard();

#endif
114 changes: 114 additions & 0 deletions inc/tusb_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_

#ifdef __cplusplus
extern "C" {
#endif

//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------

// defined by board.mk
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif

// RHPort number used for device can be defined by board.mk, default to port 0
#ifndef BOARD_DEVICE_RHPORT_NUM
#define BOARD_DEVICE_RHPORT_NUM 0
#endif

// RHPort max operational speed can defined by board.mk
// Default to max (auto) speed for MCU with internal HighSpeed PHY
#ifndef BOARD_DEVICE_RHPORT_SPEED
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
#endif

// Device mode with rhport and speed defined by board.mk
#if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#else
#error "Incorrect RHPort configuration"
#endif

// This example doesn't use an RTOS
#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_NONE
#endif

// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0

/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif

#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif

//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------

#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif

//------------- CLASS -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID 0
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0

// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

// CDC Endpoint transfer buffer size, more is faster
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_EP_BUFSIZE 512

#ifdef __cplusplus
}
#endif

#endif /* _TUSB_CONFIG_H_ */
20 changes: 20 additions & 0 deletions src/lfs_disk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "lfs_disk.h"

const struct lfs_config LFS_CFG = {
// block device operations
.read = lfs_flash_read,
.prog = lfs_flash_prog,
.erase = lfs_flash_erase,
.sync = lfs_flash_sync,

// block device configuration
.read_size = 256,
.prog_size = 256,
.block_size = LFS_BLOCK_SIZE,
.block_count = LFS_BLOCK_COUNT, // 4096 * 64 = 256KB
.cache_size = 256,
.lookahead_size = 64,
.block_cycles = 500,
};

__attribute__((section(".lfs"))) const uint8_t LFS_SPACE[LFS_BLOCK_COUNT * LFS_BLOCK_SIZE]; // space allocated to LFS
46 changes: 46 additions & 0 deletions src/lfs_flash_handler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "lfs_flash_handler.h"
#include "lfs_disk.h"
#include "hardware/sync.h"
#include "hardware/flash.h"

extern uint32_t __flash_binary_start;
extern uint32_t __lfs_start;

// Read a region in a block. Negative error codes are propagated
// to the user.
int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
for(uint32_t i = 0; i < size; i++) {
//uint8_t temp = *((uint8_t *)&__lfs_start);
uint8_t temp = *((uint8_t*)(uint32_t)&__lfs_start + (block * LFS_BLOCK_SIZE + off + i));
((uint8_t*) buffer)[i] = temp;
}
return LFS_ERR_OK;
}

// Program a region in a block. The block must have previously
// been erased. Negative error codes are propagated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
int lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
uint32_t int_status = save_and_disable_interrupts();
flash_range_program((uint32_t)&__lfs_start - (uint32_t)&__flash_binary_start + (block * LFS_BLOCK_SIZE) + off, (const uint8_t*) buffer, size);
restore_interrupts(int_status);
return LFS_ERR_OK;
}

// Erase a block. A block must be erased before being programmed.
// The state of an erased block is undefined. Negative error codes
// are propagated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block) {
uint32_t int_status = save_and_disable_interrupts();
flash_range_erase((uint32_t)&__lfs_start - (uint32_t)&__flash_binary_start + (block * LFS_BLOCK_SIZE), LFS_BLOCK_SIZE);
restore_interrupts(int_status);
return LFS_ERR_OK;
}

// Sync the state of the underlying block device. Negative error codes
// are propagated to the user.
int lfs_flash_sync(const struct lfs_config *c) {
/* Pico flash primitives ensure that the cache is always flushed after each write operation */
return LFS_ERR_OK;
}
Loading

0 comments on commit 507555e

Please sign in to comment.