Skip to content

Commit 9ea6468

Browse files
committed
Merge branch 'pmc+/development' into pmc+/release
2 parents b31d37a + e11ce0f commit 9ea6468

File tree

15 files changed

+636
-523
lines changed

15 files changed

+636
-523
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "no-OS-FatFS-SD-SPI-RPi-Pico"]
22
path = no-OS-FatFS-SD-SPI-RPi-Pico
3-
url = git@github.com:carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git
3+
url = https://github.com/carlk3/no-OS-FatFS-SD-SPI-RPi-Pico.git

CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
cmake_minimum_required(VERSION 3.13)
22

3+
set(PICO_BOARD pico_w)
4+
35
include(pico_sdk_import.cmake)
46

57
project(picomemcard_project C CXX ASM)
@@ -15,6 +17,7 @@ pico_generate_pio_header(PicoMemcard ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
1517

1618
add_definitions(-DNO_PICO_LED) # prevent SD SPI library from using LED
1719
add_subdirectory(no-OS-FatFS-SD-SPI-RPi-Pico/FatFs_SPI PicoMemcard)
20+
add_subdirectory(poc_examples)
1821

1922
# Example source
2023
target_sources(PicoMemcard PUBLIC
@@ -35,6 +38,18 @@ target_include_directories(PicoMemcard PUBLIC
3538

3639
pico_enable_stdio_uart(PicoMemcard 1) # enable only UART stdio
3740

38-
target_link_libraries(PicoMemcard pico_stdlib pico_multicore pico_time hardware_pio tinyusb_device tinyusb_board FatFs_SPI)
41+
target_link_libraries(
42+
PicoMemcard
43+
pico_stdlib
44+
pico_multicore
45+
pico_time
46+
hardware_pio
47+
tinyusb_device
48+
tinyusb_board
49+
FatFs_SPI
50+
51+
pico_cyw43_arch_none # If you do not need the TCP/IP stack but wish to use the on-board LED on a Pico W
52+
hardware_adc
53+
)
3954

4055
pico_add_extra_outputs(PicoMemcard)

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Memory card images must be exactly 128KB (131072 bytes) in size. PicoMemcard and
104104
For other file formats, try using [MemcardRex] for converting to the desired output.
105105

106106
* **PicoMemcard** only supports a single image which must be named exactly `MEMCARD.MCR`.
107-
* **PicoMemcard+** supports hundreds of images. Each image must be named `N.MCR` where `N` is an integer number (e.g. `0.MCR`, `1.MCR`...). On boot the first image loaded will always be the one with the lowest number.
107+
* **PicoMemcard+** supports hundreds of images. Each image must be named `N.MCR` where `N` is an integer number (e.g. `0.MCR`, `1.MCR`...). On boot your previously loaded image will be reloaded, unless it's a fresh card then `0.MCR` will be loaded.
108108

109109
Inside `docs/images` you can find two memory card images. One has a couple of saves on it so you can test if everything works correctly, the other is completely empty.
110110

@@ -122,11 +122,11 @@ Additionally this method does not work on PS2 Memory Cards and Controllers are w
122122
## Syncing Changes
123123
Generally speaking, new data written to PicoMemcard (e.g. when you save) is permanently stored only after a short period of time (due to hardware limitation). The on board LED indicates whether all changes have been stored or not, in particular:
124124
* On Rapsbery Pi Pico the LED will be on when all changes have been saved, off otherwise.
125-
* On RP2040-Zero the LED will be green when all changes have been saved, yellow otherwise
125+
* On RP2040-Zero the LED will be solid green when all changes have been saved, red otherwise.
126126

127127
Unlike **PicoMemcard+** that tries to write new changes as soon as possible, **PicoMemcard** will generally do it only after a period of inactivity (around 5 seconds). If you want to force **PicoMemcard** to immediately sync you can press `START + SELECT + TRIANGLE`.
128128

129-
**Attention**: after you save your game, make sure to wait for the LED to be green before turning off the console otherwise you might lose your more recent progress!
129+
**Attention**: after you save your game, make sure to wait for the LED to be solid green before turning off the console otherwise you might lose your more recent progress!
130130

131131
## 3D-Printed Case
132132
I've finally designed a 3D-printable case for the different PicoMemcard PCBs. It helps inserting correctly the PCB and ensuring that the the connection to the PSX is optimal. The same result, albeit more janky, can be achieved using a folded sheet of paper as a spacer.
@@ -153,15 +153,15 @@ In particular, the RP2040-Zero has RGB LED that provides a more clear output. Th
153153
| Status | Pico | RP2040-Zero
154154
| --- | --- | --- |
155155
| Failed to read memory card image | Slow blinking led | Red blinking led
156-
| Data not fully synced (do not turn off PSX)| Led off | Yellow led |
157-
| Data synced | Led on | Green led |
156+
| Data not fully synced (do not turn off PSX)| Led off | Red led (or flashing red and green) |
157+
| Data synced | Led on | Green solid led |
158158

159159
### PicoMemcard+ Status
160160
| Status | Pico | RP2040-Zero
161161
| --- | --- | --- |
162162
| Failed to read SD card | Blinking led | Red blinking led
163-
| Data not fully synced (do not turn off PSX)| Led off | Yellow led |
164-
| Data synced | Led on | Green led |
163+
| Data not fully synced (do not turn off PSX)| Led off | Red led (or flashing red and green) |
164+
| Data synced | Led on | Green solid led |
165165
| Memory Card image changed | Three fast blinks | Single blue blink |
166166
| Memory Card image not changed (end of list) | Nine fast blinks | Single orange blink |
167167
| New Memory Card image created | Multiple very fast blinks | Single light blue blink |

inc/config.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@
1313
#define PICO
1414
//#define RP2040ZERO
1515

16+
/* Invert red and green. Uncomment this if the LED colours for your RP2040 Zero are incorrect. */
17+
#define INVERT_RED_GREEN
18+
1619
/* PSX Interface Pinout */
17-
#ifdef PICO
18-
#define PIN_DAT 5
19-
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
20-
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
21-
#define PIN_CLK PIN_SEL + 1 // must be immediately after PIN_SEL
22-
#define PIN_ACK 9
20+
#ifdef PICO // TODO remove/find way to include this into pio code
21+
//#define PIN_DAT 5
22+
//#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
23+
//#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
24+
//#define PIN_CLK PIN_SEL + 1 // must be immediately after PIN_SEL
25+
//#define PIN_ACK 9
2326
#endif
2427

25-
#ifdef RP2040ZERO
28+
#ifdef RP2040ZERO // TODO remove/find way to include this into pio code
2629
#define PIN_DAT 9
2730
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
2831
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD

inc/led.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ void led_output_mc_change();
1010
void led_output_end_mc_list();
1111
void led_output_new_mc();
1212

13+
int32_t is_pico_w();
14+
void init_led(uint32_t pin);
15+
void set_led(uint32_t pin, uint32_t level);
16+
1317
#endif

inc/memcard_manager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
bool memcard_manager_exist(uint8_t* filename);
1818
uint32_t memcard_manager_count();
1919
uint32_t memcard_manager_get(uint32_t index, uint8_t* out_filename);
20-
#define memcard_manager_get_first(out_filename) memcard_manager_get(0, (out_filename))
20+
#define memcard_manager_get_initial(out_filename) memcard_manager_get(memcard_manager_get_prev_loaded_memcard_index(), (out_filename))
21+
uint32_t memcard_manager_get_prev_loaded_memcard_index();
2122
uint32_t memcard_manager_get_next(uint8_t* filename, uint8_t* out_nextfile);
2223
uint32_t memcard_manager_get_prev(uint8_t* filename, uint8_t* out_prevfile);
2324
uint32_t memcard_manager_create(uint8_t* out_filename);

poc_examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_subdirectory(controller_simulator)
2+
add_subdirectory(memcard_sniffer)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
include(${CMAKE_SOURCE_DIR}/pico_sdk_import.cmake)
4+
5+
project(controller_simulator C CXX ASM)
6+
set(CMAKE_C_STANDARD 11)
7+
set(CMAKE_CXX_STANDARD 17)
8+
pico_sdk_init()
9+
10+
add_executable(controller_simulator)
11+
12+
pico_generate_pio_header(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/psxSPI.pio)
13+
14+
target_sources(${PROJECT_NAME} PUBLIC
15+
${CMAKE_CURRENT_SOURCE_DIR}/controller_simulator.c
16+
)
17+
18+
pico_enable_stdio_uart(${PROJECT_NAME} 1)
19+
20+
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_pio)
21+
22+
pico_add_extra_outputs(${PROJECT_NAME})

poc_examples/controller_simulator.c renamed to poc_examples/controller_simulator/controller_simulator.c

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@ PIO pio = pio0;
3333

3434
uint smSelMonitor;
3535
uint smCmdReader;
36-
uint smAckSender;
3736
uint smDatWriter;
3837

3938
uint offsetSelMonitor;
4039
uint offsetCmdReader;
4140
uint offsetDatWriter;
42-
uint offsetAckSender;
4341

4442
static uint count = 0;
4543

@@ -62,48 +60,48 @@ void cancel_ack() {
6260

6361
void process_joy_req(uint8_t next_byte) {
6462
printf("\n%.2x ", next_byte);
65-
write_dat_LSB_blocking(pio, smDatWriter, ID_LO); // write lower ID byte
63+
write_byte_blocking(pio, smDatWriter, ID_LO); // write lower ID byte
6664

67-
next_byte = read_cmd_byte_blocking(pio, smCmdReader);
65+
next_byte = read_byte_blocking(pio, smCmdReader);
6866
if(next_byte != 0x42) {
6967
printf("\nWaiting for %.2x but received %.2x\n", 0x42, next_byte);
7068
return;
7169
} else {
72-
write_dat_LSB_blocking(pio, smDatWriter, ID_HI); // write upper ID byte
70+
write_byte_blocking(pio, smDatWriter, ID_HI); // write upper ID byte
7371
printf("%.2x ", next_byte);
7472
}
7573

76-
next_byte = read_cmd_byte_blocking(pio, smCmdReader);
74+
next_byte = read_byte_blocking(pio, smCmdReader);
7775
if(next_byte != 0x00) {
7876
printf("\nWaiting for %.2x but received %.2x\n", 0x00, next_byte);
7977
return;
8078
} else {
8179
switch (count) {
8280
case 0:
83-
write_dat_LSB_blocking(pio, smDatWriter, R_PRESSED); // fake right d-pad being pressed
81+
write_byte_blocking(pio, smDatWriter, R_PRESSED); // fake right d-pad being pressed
8482
break;
8583
case 2:
86-
write_dat_LSB_blocking(pio, smDatWriter, L_PRESSED); // fake left d-pad being pressed
84+
write_byte_blocking(pio, smDatWriter, L_PRESSED); // fake left d-pad being pressed
8785
break;
8886
case 1:
8987
case 3:
9088
default:
91-
write_dat_LSB_blocking(pio, smDatWriter, NO_PRESSED); // release all buttons
89+
write_byte_blocking(pio, smDatWriter, NO_PRESSED); // release all buttons
9290
break;
9391
}
9492
printf("%.2x ", next_byte);
9593
}
9694

97-
next_byte = read_cmd_byte_blocking(pio, smCmdReader);
95+
next_byte = read_byte_blocking(pio, smCmdReader);
9896
if(next_byte != 0x00) {
9997
printf("\nWaiting for %.2x but received %.2x\n", 0x00, next_byte);
10098
return;
10199
} else {
102-
write_dat_LSB_blocking(pio, smDatWriter, NO_PRESSED); // other buttons are all inactive
100+
write_byte_blocking(pio, smDatWriter, NO_PRESSED); // other buttons are all inactive
103101
printf("%.2x ", next_byte);
104102
}
105103

106-
next_byte = read_cmd_byte_blocking(pio, smCmdReader);
104+
next_byte = read_byte_blocking(pio, smCmdReader);
107105
cancel_ack(); // last byte being received, no need to send more data
108106
if(next_byte != 0x00) {
109107
printf("\nWaiting for %.2x but received %.2x\n", 0x00, next_byte);
@@ -124,27 +122,23 @@ int main() {
124122

125123
offsetSelMonitor = pio_add_program(pio, &sel_monitor_program);
126124
offsetCmdReader = pio_add_program(pio, &cmd_reader_program);
127-
offsetAckSender = pio_add_program(pio, &ack_sender_program);
128125
offsetDatWriter = pio_add_program(pio, &dat_writer_program);
129126

130127
smSelMonitor = pio_claim_unused_sm(pio, true);
131128
smCmdReader = pio_claim_unused_sm(pio, true);
132-
smAckSender = pio_claim_unused_sm(pio, true);
133129
smDatWriter = pio_claim_unused_sm(pio, true);
134130

135131
dat_writer_program_init(pio, smDatWriter, offsetDatWriter, PIN_DAT, PIN_CLK);
136-
ack_sender_program_init(pio, smAckSender, offsetAckSender, PIN_ACK);
137-
cmd_reader_program_init(pio, smCmdReader, offsetCmdReader, PIN_CMD);
132+
cmd_reader_program_init(pio, smCmdReader, offsetCmdReader, PIN_CMD, PIN_ACK);
138133
sel_monitor_program_init(pio, smSelMonitor, offsetSelMonitor, PIN_SEL);
139134

140-
141135
/* Enable all SM simultaneously */
142-
uint32_t smMask = (1 << smSelMonitor) | (1 << smCmdReader) | (1 << smAckSender) | (1 << smDatWriter);
136+
uint32_t smMask = (1 << smSelMonitor) | (1 << smCmdReader) | (1 << smDatWriter);
143137
pio_enable_sm_mask_in_sync(pio, smMask);
144138

145139
uint32_t i = 0;
146140
while(true) {
147-
uint8_t item = read_cmd_byte_blocking(pio, smCmdReader);
141+
uint8_t item = read_byte_blocking(pio, smCmdReader);
148142

149143
if(item == 0x01)
150144
process_joy_req(item);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
include(${CMAKE_SOURCE_DIR}/pico_sdk_import.cmake)
4+
5+
project(memcard_sniffer C CXX ASM)
6+
set(CMAKE_C_STANDARD 11)
7+
set(CMAKE_CXX_STANDARD 17)
8+
pico_sdk_init()
9+
10+
add_executable(memcard_sniffer)
11+
12+
pico_generate_pio_header(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/psxSPI.pio)
13+
14+
target_sources(${PROJECT_NAME} PUBLIC
15+
${CMAKE_CURRENT_SOURCE_DIR}/memcard_sniffer.c
16+
)
17+
18+
pico_enable_stdio_uart(${PROJECT_NAME} 1)
19+
20+
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_pio)
21+
22+
pico_add_extra_outputs(${PROJECT_NAME})

poc_examples/memcard_sniffer.c renamed to poc_examples/memcard_sniffer/memcard_sniffer.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ int main() {
6868
smDatReader = pio_claim_unused_sm(pio, true);
6969

7070
dat_reader_program_init(pio, smDatReader, offsetDatReader, PIN_DAT);
71-
cmd_reader_program_init(pio, smCmdReader, offsetCmdReader, PIN_CMD);
71+
cmd_reader_program_init(pio, smCmdReader, offsetCmdReader, PIN_CMD, PIN_ACK);
7272
sel_monitor_program_init(pio, smSelMonitor, offsetSelMonitor, PIN_SEL);
7373

7474
/* Enable all SM simultaneously */
@@ -77,8 +77,8 @@ int main() {
7777

7878
/* Samping phase */
7979
for(int i = 0; i < BUFF_LEN; ++i) {
80-
cmdBuffer[index] = read_byte_blocking(pio, smCmdReader);
81-
datBuffer[index] = read_byte_blocking(pio, smDatReader);
80+
cmdBuffer[i] = read_byte_blocking(pio, smCmdReader);
81+
datBuffer[i] = read_byte_blocking(pio, smDatReader);
8282
}
8383

8484
/* Printing results */

0 commit comments

Comments
 (0)