Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8037

SDK • Outputting wrong data via PIO

$
0
0
Hello!
I am working on an open source library for emulating a playstation 2 controller. I have the reading portion (what the console sends me) working correctly, but it seems that when it comes to outputting data, I'm sending gibberish.

The PIO program that handles output is the following. If you think the one that does the reading is relevant, I can post it too:

Code:

.program dualshock_data.wrap_targetset pindirs 0wait_for_output:jmp !osre wait_for_att  ;; Stall while we don't have data to outputjmp wait_for_outputwait_for_att:set x, 7                ;; Set bit counter: we want to send a byte.wait 0 pin 0            ;; Wait for ATT.;;; set pindirs 1           ;; Drive ACK low;;;     set pins 0 [5];;;     set pindirs 0       out_loop:wait 0 pin 1            ;; When clock drops from low to high,wait 1 pin 1            ;; send our data.out pindirs, 1          ;; Send a bit to the PS2.jmp x-- out_loop        ;; Decrement bit counter..wrap;; Configuration% c-sdk {  void dualshock_data_program_init(PIO pio, uint sm, uint offset, uint data_pin,                                   uint att_pin, uint ack_pin) {    pio_sm_config cfg = dualshock_data_program_get_default_config(offset);    sm_config_set_in_pins(&cfg, att_pin);    pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, false);    sm_config_set_set_pins(&cfg, data_pin, 1);    sm_config_set_out_pins(&cfg, data_pin, 1);    sm_config_set_out_shift(&cfg, true, true, 8);    sm_config_set_clkdiv_int_frac(&cfg, 50, 0);        pio_gpio_init(pio, data_pin);    pio_sm_init(pio, sm, offset, &cfg);  }%}
On the C part, the algorithm is simple: I read a byte, and switch cases according to what I want to send in response:

Code:

// Includes, defines, etc. As always, not relevant here, but if you'd like more context I can post it.int main() {  stdio_init_all();  // Configuration  uint32_t data = 0xff;  PIO pio = pio0;  PIO data_pio = pio1;  uint sm = pio_claim_unused_sm(pio, true);  uint data_sm = pio_claim_unused_sm(data_pio, true);  uint offset = pio_add_program(pio, &dualshock_program);  uint data_offset = pio_add_program(data_pio, &dualshock_data_program);  pio_sm_clear_fifos(pio, sm);  pio_sm_clear_fifos(data_pio, sm);  dualshock_program_init(pio, sm, offset, COMMAND_PIN, ACK_PIN);  dualshock_data_program_init(data_pio, data_sm, data_offset, DATA_PIN, ATT_PIN, ACK_PIN);  pio_sm_set_enabled(pio, sm, true);  pio_sm_set_enabled(data_pio, data_sm, true);  // Main loop.  while (true) {    data = pio_sm_get_blocking(pio, sm) >> 24;    switch (data) {    case 0x01:      pio_sm_put_blocking(data_pio, data_sm, (0xff ^ 0xff));      break;    case 0x42:      pio_sm_put_blocking(data_pio, data_sm, (0xff ^ 0x41));      break;    case 0x00:      pio_sm_put_blocking(data_pio, data_sm, (0xff ^ 0x5a));      uint32_t buf = pio_sm_get_blocking(pio, sm) >> 24;            if (buf != 0x00)        continue;      pio_sm_put_blocking(data_pio, data_sm, (0xff ^ 0xff));      buf = pio_sm_get_blocking(pio, sm) >> 24;       if (buf != 0x00)        continue;      pio_sm_put_blocking(data_pio, data_sm, (0xff ^ 0x40));      break;    }     printf("%x\n", data);  }  return 0;}
Basically, for every byte I receive, I want to send the following:
  • I receive 0x01, I send 0xff
  • I receive 0x42, I send 0x41
  • I receive 0x00, I send 0x5a
  • For the following bytes, the playstation 2 expects data from my part (e.g. button presses)
  • I receive 0x00, I send 0xff
  • I receive 0x00, I send 0x40 (Circle is pressed down)
If you'd like a better explanation of the back and forth communication I want to achieve. Here's a table with the example I want to emulate.

The following are some screenshots of a logic analyzer to peek at what I'm sending. The interesting part is that sometimes I do send the bytes I want, preceded or followed by gibberish. Do note that we read data least significant bit first and DAT is the output line, CMD is the input line.

First cycle. Supposedly I sent the byte 0x81:
first_cycle.png
Second cycle, I sent 0xDA:
second_cycle.png
Thanks for the help!

Statistics: Posted by hombrelaser — Sat Jul 26, 2025 7:59 pm



Viewing all articles
Browse latest Browse all 8037

Trending Articles