Adding pinout and parity check to PS/2 implementation

This commit is contained in:
Rodrigo Alfonso
2024-08-05 10:28:27 -03:00
parent af429fa565
commit b7bcd7848d
2 changed files with 56 additions and 15 deletions

View File

@@ -24,7 +24,7 @@ A set of Game Boy Advance (GBA) C++ libraries to interact with the Serial Port.
## Usage
- Include the library you want (e.g. [LinkCable.hpp](lib/LinkCable.hpp)) in your game code, and refer to its comments for instructions. Most of these libraries are provided as single header files for simplicity. The only external dependency is **libtonc**, which comes preinstalled with *devkitPro*.
- Include the library you want (e.g. [LinkCable.hpp](lib/LinkCable.hpp)) in your game code, and refer to its comments for instructions. Most of these libraries are provided as single header files for simplicity. The only external dependency is **libtonc**, which comes preinstalled with *devkitARM*.
- Check out the [examples](examples) folder.
* Builds are available in [Releases](https://github.com/afska/gba-link-connection/releases).
* They can be tested on real GBAs or using emulators.
@@ -406,6 +406,18 @@ Name | Return type | Description
`deactivate()` | - | Deactivates the library.
`report(data[3])` | - | Fills the `data` int array with a report. The first int contains _clicks_ that you can check against the bitmasks `LINK_PS2_MOUSE_LEFT_CLICK`, `LINK_PS2_MOUSE_MIDDLE_CLICK`, and `LINK_PS2_MOUSE_RIGHT_CLICK`. The second int is the _X movement_, and the third int is the _Y movement_.
## Pinout
```
____________
|PS/2 --- GBA|
|------------|
|CLOCK -> SI |
|DATA --> SO |
|VCC ---> VCC|
|GND ---> GND|
```
# ⌨️ LinkPS2Keyboard
A PS/2 keyboard driver for the GBA. Use it to add keyboard support to your homebrew games.
@@ -422,4 +434,16 @@ Name | Return type | Description
--- | --- | ---
`isActive()` | **bool** | Returns whether the library is active or not.
`activate()` | - | Activates the library.
`deactivate()` | - | Deactivates the library.
`deactivate()` | - | Deactivates the library.
## Pinout
```
____________
|PS/2 --- GBA|
|------------|
|CLOCK -> SI |
|DATA --> SO |
|VCC ---> VCC|
|GND ---> GND|
```

View File

@@ -78,6 +78,7 @@ class LinkPS2Keyboard {
bitcount = 0;
incoming = 0;
parityBit = 0;
prevFrame = 0;
frameCounter = 0;
@@ -94,33 +95,52 @@ class LinkPS2Keyboard {
void _onVBlank() { frameCounter++; }
void _onSerial() {
if (!isEnabled)
return;
u8 val = (REG_RCNT & LINK_PS2_KEYBOARD_SO_DATA) != 0;
u32 nowFrame = frameCounter;
if (nowFrame - prevFrame > LINK_PS2_KEYBOARD_TIMEOUT_FRAMES) {
bitcount = 0;
incoming = 0;
parityBit = 0;
}
prevFrame = nowFrame;
u8 n = bitcount - 1;
if (n <= 7)
incoming |= (val << n);
bitcount++;
if (bitcount == 11) {
onEvent(incoming);
if (bitcount == 0 && val == 0) { // start bit detected
// start bit is always 0, so only proceed if val is 0
bitcount++;
} else if (bitcount >= 1 && bitcount <= 8) { // data bits
incoming |= (val << (bitcount - 1));
bitcount++;
} else if (bitcount == 9) { // parity bit
// store parity bit for later check
parityBit = val;
bitcount++;
} else if (bitcount == 10) { // stop bit
if (val == 1) { // stop bit should be 1
// calculate parity (including the stored parity bit from previous IRQ)
u8 parity = 0;
for (u8 i = 0; i < 8; i++)
parity += (incoming >> i) & 1;
parity += parityBit;
if (parity % 2 != 0) // odd parity as expected
onEvent(incoming);
}
bitcount = 0;
incoming = 0;
parityBit = 0;
}
}
private:
bool isEnabled = false;
uint8_t bitcount = 0;
uint8_t incoming = 0;
uint32_t prevFrame = 0;
u8 bitcount = 0;
u8 incoming = 0;
u8 parityBit = 0;
u32 prevFrame = 0;
u32 frameCounter = 0;
std::function<void(u8 event)> onEvent;
};
@@ -135,9 +155,6 @@ inline void LINK_PS2_KEYBOARD_ISR_VBLANK() {
}
inline void LINK_PS2_KEYBOARD_ISR_SERIAL() {
if (!linkPS2Keyboard->isActive())
return;
linkPS2Keyboard->_onSerial();
}