Skip to content

Commit

Permalink
Added USB debug commands handling + file_get_sectors refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Polprzewodnikowy committed Sep 4, 2023
1 parent c44ff7f commit f063f05
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 47 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ SRCS = \
menu/rom_database.c \
menu/settings.c \
menu/sound.c \
menu/usb_comm.c \
menu/views/browser.c \
menu/views/credits.c \
menu/views/error.c \
Expand Down
10 changes: 8 additions & 2 deletions localdeploy.bat
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ echo !!! Now toggle power to the N64 !!!
echo:
echo:

if not "%1" == "/d" goto :exit
if not "%1" == "/d" goto :not_d

%~dp0tools\sc64\sc64deployer debug --no-writeback

:exit
:not_d

if not "%1" == "/du" goto :not_du

%~dp0tools\sc64\sc64deployer debug --no-writeback --init "send-file /sc64menu.n64 @output/sc64menu.n64@;reboot"

:not_du
24 changes: 4 additions & 20 deletions remotedeploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,12 @@ set -e

REMOTE="--remote ${REMOTE:-host.docker.internal:9064}"

## FIXME: this does not work!
# Make sure we are connected
#echo Detecting SC64...
#sc64deployer $REMOTE list

# Get the information
echo SC64 info...:
sc64deployer $REMOTE info
echo
echo

# Load the ROM
echo Loading ROM...:
sc64deployer $REMOTE upload ./output/N64FlashcartMenu.n64

echo
echo
# Toggle the power of the N64 to boot the ROM.
echo !!! Now toggle power to the N64 !!!
echo
echo

if [ "$1" = "-d" ]; then
sc64deployer $REMOTE debug --no-writeback
fi

if [ "$1" = "-du" ]; then
sc64deployer $REMOTE debug --no-writeback --init "send-file /sc64menu.n64 @output/sc64menu.n64@;reboot"
fi
27 changes: 23 additions & 4 deletions src/flashcart/flashcart.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "sc64/sc64.h"


#define WRITEBACK_MAX_SECTORS (256)
#define SAVE_WRITEBACK_MAX_SECTORS (256)


static const size_t SAVE_SIZE[__FLASHCART_SAVE_TYPE_END] = {
Expand All @@ -24,6 +24,9 @@ static const size_t SAVE_SIZE[__FLASHCART_SAVE_TYPE_END] = {
KiB(128),
};

static uint32_t save_writeback_sectors[SAVE_WRITEBACK_MAX_SECTORS] __attribute__((aligned(8)));


static flashcart_error_t dummy_init (void) {
return FLASHCART_OK;
}
Expand Down Expand Up @@ -95,6 +98,7 @@ flashcart_error_t flashcart_deinit (void) {
if (flashcart->deinit) {
return flashcart->deinit();
}

return FLASHCART_OK;
}

Expand Down Expand Up @@ -124,9 +128,21 @@ flashcart_error_t flashcart_load_file (char *file_path, uint32_t rom_offset, uin
return flashcart->load_file(file_path, rom_offset, file_offset);
}

static void save_writeback_sectors_callback (uint32_t sector_count, uint32_t file_sector, uint32_t cluster_sector, uint32_t cluster_size) {
for (uint32_t i = 0; i < cluster_size; i++) {
uint32_t offset = file_sector + i;
uint32_t sector = cluster_sector + i;

if ((offset > SAVE_WRITEBACK_MAX_SECTORS) || (offset > sector_count)) {
return;
}

save_writeback_sectors[offset] = sector;
}
}

flashcart_error_t flashcart_load_save (char *save_path, flashcart_save_type_t save_type) {
flashcart_error_t error;
uint32_t sectors[WRITEBACK_MAX_SECTORS] __attribute__((aligned(8)));

if (save_type >= __FLASHCART_SAVE_TYPE_END) {
return FLASHCART_ERROR_ARGS;
Expand Down Expand Up @@ -158,10 +174,13 @@ flashcart_error_t flashcart_load_save (char *save_path, flashcart_save_type_t sa
}

if (flashcart->set_save_writeback) {
if (file_get_sectors(save_path, sectors, WRITEBACK_MAX_SECTORS)) {
for (int i = 0; i < SAVE_WRITEBACK_MAX_SECTORS; i++) {
save_writeback_sectors[i] = 0;
}
if (file_get_sectors(save_path, save_writeback_sectors_callback)) {
return FLASHCART_ERROR_LOAD;
}
if ((error = flashcart->set_save_writeback(sectors)) != FLASHCART_OK) {
if ((error = flashcart->set_save_writeback(save_writeback_sectors)) != FLASHCART_OK) {
return error;
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/flashcart/sc64/sc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static flashcart_error_t sc64_init (void) {
uint32_t value;
} default_config[] = {
{ CFG_ID_BOOTLOADER_SWITCH, false },
{ CFG_ID_ROM_WRITE_ENABLE, false },
{ CFG_ID_ROM_WRITE_ENABLE, true },
{ CFG_ID_ROM_SHADOW_ENABLE, false },
{ CFG_ID_DD_MODE, DD_MODE_DISABLED },
{ CFG_ID_ISV_ADDRESS, 0x00000000 },
Expand All @@ -110,6 +110,8 @@ static flashcart_error_t sc64_init (void) {
}

static flashcart_error_t sc64_deinit (void) {
sc64_ll_set_config(CFG_ID_ROM_WRITE_ENABLE, false);

sc64_ll_lock();

return FLASHCART_OK;
Expand Down
3 changes: 3 additions & 0 deletions src/menu/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "png_decoder.h"
#include "settings.h"
#include "sound.h"
#include "usb_comm.h"
#include "utils/fs.h"
#include "views/views.h"

Expand Down Expand Up @@ -180,6 +181,8 @@ void menu_run (boot_params_t *boot_params) {
sound_poll();

png_decoder_poll();

usb_comm_poll(menu);
}

menu_deinit(menu);
Expand Down
163 changes: 163 additions & 0 deletions src/menu/usb_comm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// NOTE: This code doesn't implement EverDrive-64 USB protocol.
// Main use of these functions is to aid menu development
// (for example replace files on the SD card or reboot menu).

#include <fatfs/ff.h>
#include <string.h>
#include <usb.h>

#include "usb_comm.h"
#include "utils/utils.h"


#define MAX_FILE_SIZE MiB(4)


typedef struct {
const char *id;
void (*op) (menu_t *menu);
} usb_comm_command_t;


static int usb_comm_get_char (void) {
char c;

if (USBHEADER_GETSIZE(usb_poll()) <= 0) {
return -1;
}

usb_read(&c, sizeof(c));

return (int) (c);
}

static bool usb_comm_read_string (char *string, int length, char end) {
for (int i = 0; i < length; i++) {
int c = usb_comm_get_char();

if (c < 0) {
return true;
}

string[i] = (char) (c);

if (c == '\0' || c == end) {
string[i] = '\0';
break;
}

if (i == (length - 1)) {
return true;
}
}

return false;
}

static void usb_comm_send_error (const char *message) {
usb_purge();
usb_write(DATATYPE_TEXT, message, strlen(message));
}


static void command_reboot (menu_t *menu) {
menu->next_mode = MENU_MODE_BOOT;

menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
menu->boot_params->detect_cic_seed = true;
};

static void command_send_file (menu_t *menu) {
char path[256];
char length[8];

FIL f;
int remaining;
uint8_t data[8192];
UINT bytes_written;

if (usb_comm_read_string(path, sizeof(path), ' ')) {
return usb_comm_send_error("Invalid path argument\n");
}

if (usb_comm_get_char() != '@') {
return usb_comm_send_error("Invalid argument\n");
}

if (usb_comm_read_string(length, sizeof(length), '@')) {
return usb_comm_send_error("Invalid file length argument\n");
}

if (f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
return usb_comm_send_error("Couldn't create file\n");
}

remaining = atoi(length);

if (remaining > MAX_FILE_SIZE) {
return usb_comm_send_error("File size too big\n");
}

while (remaining > 0) {
int block_size = MIN(remaining, sizeof(data));
usb_read(data, block_size);
if (f_write(&f, data, block_size, &bytes_written) != FR_OK) {
f_close(&f);
return usb_comm_send_error("Couldn't write data to the file\n");
}
if (bytes_written != block_size) {
f_close(&f);
return usb_comm_send_error("Couldn't write all required data to the file\n");
}
remaining -= block_size;
}

if (f_close(&f) != FR_OK) {
return usb_comm_send_error("Couldn't flush data to the file\n");
}

if (usb_comm_get_char() != '\0') {
return usb_comm_send_error("Invalid token at the end of data stream\n");
}
}

static usb_comm_command_t commands[] = {
{ .id = "reboot", .op = command_reboot },
{ .id = "send-file", .op = command_send_file },
{ .id = NULL },
};


void usb_comm_poll (menu_t *menu) {
uint32_t header = usb_poll();

if (USBHEADER_GETTYPE(header) != DATATYPE_TEXT) {
usb_purge();
return;
}

if (USBHEADER_GETSIZE(header) > 0) {
char cmd_id[32];

if (usb_comm_read_string(cmd_id, sizeof(cmd_id), ' ')) {
usb_comm_send_error("Command id too long\n");
} else {
usb_comm_command_t *cmd = commands;

while (cmd->id != NULL) {
if (strcmp(cmd->id, cmd_id) == 0) {
cmd->op(menu);
break;
}
cmd++;
}

usb_purge();

if (cmd->id == NULL) {
usb_comm_send_error("Unknown command\n");
}
}
}
}
21 changes: 21 additions & 0 deletions src/menu/usb_comm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @file usb_comm.h
* @brief USB communication subsystem
* @ingroup menu
*/

#ifndef USB_COMM_H__
#define USB_COMM_H__


#include "menu_state.h"


#ifndef NDEBUG
void usb_comm_poll (menu_t *menu);
#else
#define usb_comm_poll(menu)
#endif


#endif

0 comments on commit f063f05

Please sign in to comment.