Skip to content

Commit

Permalink
Code refractoring, bugfixing and new features:
Browse files Browse the repository at this point in the history
- update .gitignore
- update psxPSI code
- changed simulation to state maching based (following darren approach)
- add missing NULL checks in memory_card.c
- changed allocation of memory card in RAM memory
- add global config.h file
- led now reflects sync status (ram and flash memory card)
- change auto sync delay to 5 seconds
- change MSC ram disk export to automatic (no need for safe removal)

Compilation requires fix for pico-sdk not yet merged:
raspberrypi/pico-sdk#936
  • Loading branch information
dangiu committed Jul 31, 2022
1 parent a24968f commit 8509527
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 363 deletions.
9 changes: 8 additions & 1 deletion .gitignore
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@ build/
.vscode/.cortex*

# FatFS documentation
ff14b/documents
ff14b/documents

# VSCode
.vscode/settings.json

# Clion
/.idea
/cmake-build-debug
16 changes: 0 additions & 16 deletions .vscode/settings.json

This file was deleted.

3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pico_generate_pio_header(PicoMemcard ${CMAKE_CURRENT_LIST_DIR}/psxSPI.pio)

# Example source
target_sources(PicoMemcard PUBLIC
${CMAKE_SOURCE_DIR}/src/led.c
${CMAKE_SOURCE_DIR}/src/lfs_disk.c
${CMAKE_SOURCE_DIR}/src/lfs_flash_handler.c
${CMAKE_SOURCE_DIR}/src/main.c
Expand All @@ -38,6 +39,6 @@ target_include_directories(PicoMemcard PUBLIC

pico_enable_stdio_uart(PicoMemcard 1) # enable only UART stdio

target_link_libraries(PicoMemcard pico_stdlib pico_time hardware_flash hardware_pio tinyusb_device tinyusb_board)
target_link_libraries(PicoMemcard pico_stdlib pico_multicore pico_time hardware_flash hardware_pio tinyusb_device tinyusb_board)

pico_add_extra_outputs(PicoMemcard)
32 changes: 32 additions & 0 deletions inc/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__

/* Global configuration options for PicoMemcard */
#define TUD_MOUNT_TIMEOUT 3000 // max time (in ms) before giving up on MSC mode (USB) and starting memcard simulation
#define MSC_WRITE_SYNC_TIMEOUT 1 * 1000 // time (in ms) expired since last MSC write before exporting RAM disk into LFS
#define IDLE_AUTOSYNC_TIMEOUT 5 * 1000 // time (in ms) the memory card must be inactive before automatic sync from RAM to LFS
#define MEMCARD_FILE_NAME "memcard.mcr" // name of memory card file image

/* Board targeted by build */
#define TARGET_PICO
//#define TARGET_RP2040ZERO


/* PSX Interface Pinout */
#ifdef TARGET_PICO
#define PIN_DAT 5
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
#define PIN_CLK PIN_SEL + 1 // must be immediately after PIN_SEL
#define PIN_ACK 9
#endif

#ifdef TARGET_RP2040ZERO
#define PIN_DAT 9
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
#define PIN_CLK PIN_SEL + 1 // must be immediately after PIN_SEL
#define PIN_ACK 13
#endif

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

#include "pico/stdlib.h"

void led_output_sync_status(bool out_of_sync);
void blink(int amount, int on_ms, int off_ms);
void blink_fast(int amount);
void blink_normal(int amount);
void blink_slow(int amount);

#endif
3 changes: 0 additions & 3 deletions inc/lfs_disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
#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;

Expand Down
41 changes: 26 additions & 15 deletions inc/memory_card.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#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_SEC_SIZE 128 // size of single sector in bytes
#define MC_SEC_COUNT 1024 // number of sector in one memory card
#define MC_SIZE MC_SEC_SIZE * MC_SEC_COUNT // size of memory card in bytes
#define MC_FLAG_BYTE_DEF 0x08 // bit 3 set = new memory card inserted

#define MC_ID1 0x5A
#define MC_ID2 0x5D
Expand All @@ -19,20 +19,31 @@
#define MC_BAD_SEC 0xFF
#define MC_BAD_CHK 0x4E

/* Error codes */
#define MC_OK 0
#define MC_MOUNT_ERR 1
#define MC_FILE_OPEN_ERR 2
#define MC_FILE_READ_ERR 3
#define MC_FILE_WRITE_ERR 4
#define MC_FILE_SIZE_ERR 5
#define MC_NO_INIT 6

typedef struct {
uint8_t flag_byte;
uint8_t data[MC_SIZE];
uint8_t* data;
bool out_of_sync;
uint32_t last_operation_timestamp;
} MemoryCard;

uint32_t memory_card_init(MemoryCard* mc);
bool memory_card_is_sector_valid(MemoryCard* mc, uint32_t sector);
uint8_t* memory_card_get_sector_ptr(MemoryCard* mc, uint32_t sector);
void memory_card_set_sync(MemoryCard* mc, bool out_of_sync);
bool memory_card_get_sync(MemoryCard* mc);
void memory_card_update_timestamp(MemoryCard* mc);
uint32_t memory_card_sync(MemoryCard* mc);
uint32_t memory_card_reset_seen_flag(MemoryCard* mc);
} memory_card_t;

uint32_t memory_card_init(memory_card_t* mc);
uint32_t memory_card_import(memory_card_t* mc, uint8_t* file_name);
bool memory_card_is_sector_valid(memory_card_t* mc, uint32_t sector);
uint8_t* memory_card_get_sector_ptr(memory_card_t* mc, uint32_t sector);
void memory_card_set_sync(memory_card_t* mc, bool out_of_sync);
bool memory_card_get_sync(memory_card_t* mc);
void memory_card_update_timestamp(memory_card_t* mc);
bool memory_card_sync_required(memory_card_t* mc);
uint32_t memory_card_sync(memory_card_t* mc);
void memory_card_reset_seen_flag(memory_card_t* mc);

#endif
30 changes: 19 additions & 11 deletions psxSPI.pio
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ irq set 0 ; signal CPU that SEL went high
; waits for sel_monitor signal before starting execution
sel_high:
irq wait 4 ; wait for SEL monitor to signal SM start
set x, 7 ; set the bit counter
.wrap_target
recv:
wait 0 pin 2 ; wait for clock to fall
wait 1 pin 2 ; wait for rising clock edge
in pins 1 ; sample 1 bit form CMD line
irq clear 1 ; signal ACK timer to start
in pins 1 ; sample 1 bit from CMD line
jmp x-- recv ; receive and count 8 bits
set x, 7 ; reset bit counter - we now have a full byte
irq clear 5 ; trigger ack
.wrap

.program dat_reader
Expand Down Expand Up @@ -77,19 +81,17 @@ out pindirs 1 ; output 1 bit (by changing pin direction)
; Set pins mapping:
; 0 - ACK
; Program description:
; Sets ACK line low, waits for irq 1 to be lowered by cmd_reader.
; Timing is based on the first bit read by cmd_reader.
.wrap_target
irq wait 1 [31] ; 32 cycles delay (1 for instruction)
nop [23] ; 24 cycles delay (1 for instruction), total of 56 cycles
set pindirs, 1 [2] ; keep ack low for more than half PSX clock
; Sets ACK line low roughly 12uS after 8 clocks have been counted.
set pindirs, 0
.wrap_target
irq wait 5 [30] ; Wait for a byte to be received and delay for 12uS
set pindirs, 1 [5] ; keep ack low for more than half PSX clock
set pindirs, 0 ; Set ACK pin to Hi-Z
.wrap


% c-sdk {
#define ACK_CLKDIV 86 // with pico default clock (125 Mhz) results in a frequency around 6 time greater than PSX SPI frequency
#define ACK_IRQ 1
#define SLOW_CLKDIV 50 // 125MHz divided down to 2.5 MHz - we need this so we don't count clocks not meant for us on systems like the PS2

static inline void sel_monitor_program_init(PIO pio, uint sm, uint offset, uint pin_sel) {
pio_sm_config c = sel_monitor_program_get_default_config(offset);
Expand All @@ -99,6 +101,8 @@ static inline void sel_monitor_program_init(PIO pio, uint sm, uint offset, uint
pio_gpio_init(pio, pin_sel); // SEL pin
/* Interrupt Configuration */
pio_set_irq0_source_enabled(pio, pis_interrupt0, true);
/* Clock configuration */
sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00);
/* Initialize SM */
pio_sm_init(pio, sm, offset, &c);
}
Expand All @@ -114,6 +118,8 @@ static inline void cmd_reader_program_init(PIO pio, uint sm, uint offset, uint p
/* Fifo Configuration */
sm_config_set_in_shift(&c, true, true, 8); // shift ISR to right, autopush every 8 bits
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); // join RX FIFO
/* Clock configuration */
sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00);
/* Initialize SM */
pio_sm_init(pio, sm, offset, &c);
}
Expand Down Expand Up @@ -152,6 +158,8 @@ static inline void dat_writer_program_init(PIO pio, uint sm, uint offset, uint p
/* FIFO Configuration */
sm_config_set_out_shift(&c, true, true, 8); // shift OSR to right, autopull every 8 bits
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); // join TX FIFO
/* Clock configuration */
sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00);
/* Initialize SM */
pio_sm_init(pio, sm, offset, &c);
}
Expand All @@ -171,7 +179,7 @@ static inline void ack_sender_program_init(PIO pio, uint sm, uint offset, uint p
pio_sm_set_consecutive_pindirs(pio, sm, pin_ack, 1, false); // set ACK pin as input (initial configuration)
pio_gpio_init(pio, pin_ack); // init ACK pin
/* Clock Configuration */
sm_config_set_clkdiv_int_frac(&c, ACK_CLKDIV, 0x00);
sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00);
/* Initialize SM */
pio_sm_init(pio, sm, offset, &c);
}
Expand Down
40 changes: 40 additions & 0 deletions src/led.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "led.h"
#include "hardware/gpio.h"

#define LED_PIN 25

void led_output_sync_status(bool out_of_sync) {
gpio_put(LED_PIN, !out_of_sync);
}

void blink(int amount, int on_ms, int off_ms) {
bool initial_state = gpio_get(LED_PIN);
if(initial_state) {
/* turn led off if already on */
gpio_put(LED_PIN, false);
sleep_ms(off_ms);
--amount; // last blink is performed while restoring led state
}
for(int i = 0; i < amount; ++i) {
gpio_put(LED_PIN, true);
sleep_ms(on_ms);
gpio_put(LED_PIN, false);
sleep_ms(off_ms);
}
if(initial_state) {
/* restore led state */
gpio_put(LED_PIN, true);
}
}

void blink_fast(int amount) {
blink(amount, 250, 250);
}

void blink_normal(int amount) {
blink(amount, 500, 500);
}

void blink_slow(int amount) {
blink(amount, 1000, 1000);
}
3 changes: 2 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
#include "lfs_disk.h"
/* Memcard Simulation */
#include "memcard_simulator.h"
/* Global Configuration */
#include "config.h"

#define TUD_MOUNT_TIMEOUT 3000 // max time (in ms) before giving up on MSC mode and starting memcard simulation
bool tud_mount_status = false;

void cdc_task(void);
Expand Down
Loading

0 comments on commit 8509527

Please sign in to comment.