mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-10-02 13:56:42 -05:00
Adding pinout and parity check to PS/2 implementation
This commit is contained in:
28
README.md
28
README.md
@@ -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|
|
||||
```
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user