# W.H.S.P.A.H. Firmware
This is the firmware that performs RF encoding from serial input. This is designed to run on [W.H.S.P.A.H. hardware](/src/hardware/), but should work on anything that can be programmed with the [ArduinoIDE](https://www.arduino.cc/en/software/).

I'd like to mention, I am **not** a C++ developer. The code in this section is almost certainly flawed in multiple ways.
It does ~~mostly~~ work, but I'm more than happy to take constructive criticism.
If you have anything you'd like see changed in this source, please do [open an issue](https://gitea.imadumbass.dog/Brosef/WHSPAH/issues/new) regarding it.

## Packet structure:
> [!NOTE]
> There must not be any more than 200ms between each character in a packet, otherwise the read will reset.

Each packet is constructed as follows:
- `uint8_t`: Command ID.
- `any`: The data for the specific command (can also be nothing).
- `uint8_t`: A basic XOR checksum of all the previous bytes, XORed with `0x55`.
- `null`: A null terminator (0x00).

The firmware can also send logs by sending the initial character `/`, followed by ASCII text, then a null terminator (`0x00`)

### Commands:
- Connect (`0x01`): Used to get the firmware into its ready state, and out of it's initial mode of repeating `/WHSPAH\x00`. Responds with `0x01`.
- Ping (`0x02`): Needs to be send at least once every 500ms, otherwise the firmware will reset into its initial mode. Responds with `0x02`.
- Transmit (`0x10`): Transmits a CaiXianlin packet. The command's arguments are as follows:
    - `uint16_t`: Transmitter ID
    - `uint8_t`: Channel (0-2)
    - `uint8_t`: Message type (1=Shock, 2=Vibrate, 3=Beep, 4=Light)
    - `uint8_t`: Intensity (0-255)
    - `bool`: Lucal encode (required on some shockers)
