Skip to content

Commit

Permalink
Add debug and modifying gamestate documentation (#64)
Browse files Browse the repository at this point in the history
* Add debug and modifying gamestate documentation

* Fix sidebar organization
  • Loading branch information
InfraredAces authored Oct 3, 2024
1 parent 6440156 commit 04aaa05
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 4 deletions.
68 changes: 68 additions & 0 deletions development/debugging.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Debugging
# tags:
# -
pagination_next: null
pagination_prev: null
description: "Documentation on how to set up a GP2040-CE device for debugging while developing firmware features and add-ons."
---

# Debugging

Debugging is essential when developing anything in the firmware because it will help you identify and fix errors in your code, ensuring that things runs correctly. It allows you to detect syntax, logic, and runtime issues that could cause your program to crash or behave unexpectedly. The RP2040 interacts with various peripherals (e.g., GPIO, I2C, SPI). Debugging helps you ensure that these interactions are working correctly, especially when dealing with timing-sensitive operations.

By catching and resolving issues early in the development process, debugging helps you build more reliable and efficient code, saving time and preventing complex problems later on.

## UART (TTL) to USB Serial Monitor

To set up an RP2040 microcontroller to use UART communication over USB on GPIO 00 and 01, follow these steps:

### Pin Configuration

The RP2040 has two UART peripherals (UART0 and UART1). To use GPIO 00 and GPIO 01 for UART communication, you will need to leave GPIO 00 and 01 free in all GPIO pin assignments in the Board config including I2C add-ons and display, USB Host assignments or button assignments. Here's how the pins map:

- GPIO 00: UART0 TX (Transmit)
- GPIO 01: UART0 RX (Receive)

### Circuit Setup

![USB - UART Connection](https://hackster.imgix.net/uploads/attachments/1284607/image_eiE7x8afXR.png?auto=compress%2Cformat&w=740&h=555&fit=max)

- Connect USB Host to your PC to use it as a controller.
- Connect GPIO 00 (TX) to the RX pin of the USB-to-UART Serial Port Module.
- Connect GPIO 01 (RX) to the TX pin of the USB-to-UART Serial Port Module.

Make sure the ground (GND) of the RP2040 is connected to the ground of the USB-to-UART Serial Port Module to establish a common reference.

:::tip

In the event that no messages appear in serial monitor, reverse the pin connections.

:::

### Software Configuration

In the firmware, you will need to

1. Add `stdio_init_all();` to the `process()` function of your feature or add-on
2. Include the `iostream` C++ library to the executable (i.e. file.cpp)
3. Use `printf()` will output to whatever serial monitor you use to read the USB serial port.

For formatting the serial message, see https://cplusplus.com/reference/cstdio/printf/

### Read Messages via Serial Monitor

There are a number of serial monitor applications that can be used to read printed messages. Examples include, but are not limited to:

- [PuTTY](https://www.putty.org/) (Windows or Linux)
- [iTerm2](https://iterm2.com/) (MacOS)
- [picocom](https://github.com/npat-efault/picocom) (Linux)
- [Serial Monitor](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-serial-monitor) VS Code Extension (Windows, MacOS, Linux)
- [Windows Terminal](https://github.com/microsoft/terminal) (Windows)
- Default Terminal Application (Linux or MacOS)

:::note Baud Rate

By default, the baud rate is set to 115200Hz.

:::
127 changes: 127 additions & 0 deletions development/modifying-gamepad-state.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
title: Modifying Gamepad State
# tags:
# -
pagination_next: null
pagination_prev: null
description: Documentation on how to modify gamepad state when developing firmware features and add-ons"
---

# Modifying Gamepad State

In any function looking to modify the gamepad state, use a pointer to the gamepad. This is absolutely necessary for changing any aspect of gamepad state.

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
```

You can find the appropriate gamepad macros and button masks in `headers/gamepad/GamepadState.h`

## Directional Pad

To modify the gamepad's directional pad (DPad) state, use a bitwise OR assignment and the appropriate `GAMEPAD_MASK` enum to set the input as active.

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->state.dpad |= GAMEPAD_MASK_UP;
gamepad->state.dpad |= GAMEPAD_MASK_DOWN;
gamepad->state.dpad |= GAMEPAD_MASK_LEFT;
gamepad->state.dpad |= GAMEPAD_MASK_RIGHT;
```

:::note SOCD Cleaning for Add-ons

All add-ons need to handle opposing simultaneous cardinal directions within the add-on since they come after standard GPIO inputs has already been SOCD cleaned.

Consider using `runSOCDCleaner(SOCDMode mode, uint8_t dpad)` in `src/gamepad/GamepadState.cpp` to take incoming DPad inputs and then resolve them at once in the add-on's `process()` function.

:::

## Buttons

To modify the gamepad's button states, use a bitwise OR assignment and the appropriate `GAMEPAD_MASK` enum to set the input as active.

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->state.buttons |= GAMEPAD_MASK_B1;
gamepad->state.buttons |= GAMEPAD_MASK_B2;
gamepad->state.buttons |= GAMEPAD_MASK_B3;
gamepad->state.buttons |= GAMEPAD_MASK_B4;
gamepad->state.buttons |= GAMEPAD_MASK_L1;
gamepad->state.buttons |= GAMEPAD_MASK_R1;
gamepad->state.buttons |= GAMEPAD_MASK_L2;
gamepad->state.buttons |= GAMEPAD_MASK_R2;
gamepad->state.buttons |= GAMEPAD_MASK_S1;
gamepad->state.buttons |= GAMEPAD_MASK_S2;
gamepad->state.buttons |= GAMEPAD_MASK_L3;
gamepad->state.buttons |= GAMEPAD_MASK_R3;
gamepad->state.buttons |= GAMEPAD_MASK_A1;
gamepad->state.buttons |= GAMEPAD_MASK_A2;
gamepad->state.buttons |= AUX_MASK_FUNCTION;
```

## Joystick

To modify the gamepad's analog joystick state, each joystick's X- and Y-axes must be set to an unsigned integer between 0 and 65535.

```cpp
GAMEPAD_JOYSTICK_MIN = 0
GAMEPAD_JOYSTICK_MID = 0x7FFF
GAMEPAD_JOYSTICK_MAX = 0xFFFF
```

| Axis | Value Range | Joystick Position |
| :----- | :-------------- | :------------------------ |
| X-Axis | 0 - 32767 | Direction Left 100% - 0% |
| X-Axis | 32767 | Centered |
| X-Axis | 32767 - 65535 | Direction Right 0% - 100% |
| Y-Axis | 0 - 32767 | Direction Up 100% - 0% |
| Y-Axis | 32767 | Centered |
| Y-Axis | 32767 - 65535 | Direction Down 0% - 100% |

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->state.ly = value;
gamepad->state.lx = value;
gamepad->state.ry = value:
gamepad->state.rx = value:
```

:::note SOCD Cleaning for Analog Inputs

All add-ons will need to handle opposing simultaneous cardinal directions on the analog joysticks as there are no preexisting mechanisms for resolving such things elsewhere in the firmware.

:::

## Triggers

For the L2 and R2 triggers, there are two different methods for setting the values of the triggers. You can either set them digitally or using analog values.

### Digital Triggers

Similarly to other digital inputs, use a bitwise OR assignment and the appropriate `GAMEPAD_MASK` enum to set the input as active.

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->state.buttons |= GAMEPAD_MASK_L2;
gamepad->state.buttons |= GAMEPAD_MASK_R2;
```

### Analog Triggers

To set the L2 and R2 triggers to analog values, first, the gamepad's flag `hasAnalogTriggers` indicating whether the gamepad has analog triggers must be set to `true`. By default, this flag is set to `false` and it is recommended that you set this flag whenever you are manipulating analog trigger values.

Then, the appropriate axes should be set for each analog trigger. The values for analog triggers can range from 0 to 255, where 0 is fully released and 255 is fully depressed.

```cpp
GAMEPAD_TRIGGER_MIN = 0;
GAMEPAD_TRIGGER_MID = 0x7F;
GAMEPAD_TRIGGER_MAX = 0xFF;
```

```cpp
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->hasAnalogTriggers = true;
gamepad->state.lt = value;
gamepad->state.rt = value;
```
18 changes: 14 additions & 4 deletions sidebarsDevelopment.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@
"contribution-guide",
{
"type": "category",
"label": "Build and Compile",

"label": "Firmware Development",
"collapsed": false,
"items": [
"build-environment",
"board-configuration",
"compile-firmware",
{
"type": "category",
"label": "Build, Compile, Debug",
"collapsed": false,
"items": [
"build-environment",
"board-configuration",
"compile-firmware",
"debugging"
]
},
"modifying-gamepad-state",
{
"type": "category",
"label": "Add-ons",
Expand Down

0 comments on commit 04aaa05

Please sign in to comment.