Files
amiga-joymouse/main.c
T

81 lines
2.3 KiB
C

/* Baremetal Risc-V USB <=> Amiga Joystick/Mouse HID converter.
* March 2026 - Anders Holck
* This software has no license. If you choose to use, please include my name :)
*/
#include <stdint.h>
#include "usb_dwc2.h"
#include "pinmux.h"
#include "amiga_hw.h"
void delay(int count) {
for (volatile int i = 0; i < count; i++);
}
void usb_init_baremetal() {
// 1. Enable USB Clocks
uint32_t clk_en = read32(CLK_EN_1);
clk_en |= (1 << 13) | (1 << 14);
write32(CLK_EN_1, clk_en);
// 2. Power on PHY and release reset
write32(USB_PHY_CTRL, 0x07);
delay(10000);
// 3. Global Reset of DWC2 Core
write32(GRSTCTL, (1 << 0)); // Soft Reset
while (!(read32(GRSTCTL) & (1 << 29)));
delay(10000);
// 4. Force Device Mode and Basic Config
write32(GUSBCFG, (1 << 30) | (1 << 29)); // Force Device, PHY Interface
write32(DCFG, 0x0); // Full Speed
write32(GINTMSK, (1 << 12) | (1 << 13) | (1 << 4) | (1 << 18)); // Reset, Enum, RXFLVL, IEPInt
// 5. Connect
write32(DCTL, 0); // Clear Soft Disconnect
}
int main() {
pinmux_init_amiga();
usb_init_baremetal();
amiga_input_t input;
uint8_t hid_report[4] = {0}; // 2 bytes buttons, 2 bytes mouse
uint32_t report_timer = 0;
while (1) {
// 1. Poll Amiga Hardware
amiga_hw_poll(&input);
// 2. Poll USB State Machine
dwc2_poll();
// 3. Send HID Report every ~10ms (approximate)
if (++report_timer > 100) {
report_timer = 0;
// Format HID Report (Match hid_report_desc in usb_descriptors.h)
// Byte 0: Joy1 (5 bits) + Joy2 (3 bits)
// Byte 1: Joy2 (remaining 2 bits) + Padding
// Byte 2: Mouse X
// Byte 3: Mouse Y
hid_report[0] = input.joy1 | ((input.joy2 & 0x07) << 5);
hid_report[1] = (input.joy2 >> 3) & 0x03;
if (input.buttons & 0x01) hid_report[1] |= (1 << 2); // Mouse B1
if (input.buttons & 0x02) hid_report[1] |= (1 << 3); // Mouse B2
hid_report[2] = (uint8_t)input.mouse_x;
hid_report[3] = (uint8_t)input.mouse_y;
// Send via Endpoint 1 (Interrupt IN)
dwc2_send_packet(1, hid_report, 4);
}
delay(100);
}
return 0;
}