forked from tasoller/host-aprom
waow
This commit is contained in:
parent
81873aa1ec
commit
923886efde
10
.vscode/c_cpp_properties.json
vendored
10
.vscode/c_cpp_properties.json
vendored
@ -2,9 +2,15 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "GCC",
|
||||
"includePath": ["C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/arm-none-eabi/include", "NUC123/inc", "NUC123/StdDriver/inc"],
|
||||
"includePath": [
|
||||
"C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/arm-none-eabi/include",
|
||||
"C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/lib/gcc/arm-none-eabi/13.2.1/include",
|
||||
"NUC123/inc",
|
||||
"NUC123/StdDriver/inc"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "gcc-arm"
|
||||
"intelliSenseMode": "gcc-arm",
|
||||
"compilerPath": "C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/arm-none-eabi-gcc.exe"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,10 +1,12 @@
|
||||
{
|
||||
"clangd.arguments": ["--query-driver=*arm-none-eabi-*"],
|
||||
"clangd.fallbackFlags": [
|
||||
"-IC:/Program Files (x86)/GNU Arm Embedded Toolchain/13.2 Rel1/arm-none-eabi/include",
|
||||
"-IC:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/arm-none-eabi/include",
|
||||
"-IC:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/lib/gcc/arm-none-eabi/13.2.1/include",
|
||||
"-I${workspaceFolder}/NUC123/inc",
|
||||
"-I${workspaceFolder}/NUC123/StdDriver/inc",
|
||||
"-D__GNUC__",
|
||||
"-D__XSTRING(x)=", // Workaround for string.h
|
||||
"-Wno-pointer-to-int-cast",
|
||||
"-Wno-int-to-pointer-cast",
|
||||
],
|
||||
|
@ -24,4 +24,4 @@ The `NUC123` folder is a heavily reduced form of the complete BSP provided by Nu
|
||||
|
||||
`NUC123.ld` is a modified version of the GCC linker script provided by Nuvoton, and may require modification.
|
||||
|
||||
To pull in additional BSP library modules, if required, the `Makefile` should be modified.
|
||||
To pull in additional BSP drivers, if required, the `Makefile` should be modified.
|
||||
|
@ -99,6 +99,24 @@ __Vectors:
|
||||
|
||||
|
||||
Reset_Handler:
|
||||
// Unlock Register
|
||||
ldr r0, =0x50000100 // REGCTL
|
||||
movs r1, #0x59
|
||||
str r1, [r0]
|
||||
movs r1, #0x16
|
||||
str r1, [r0]
|
||||
movs r1, #0x88
|
||||
str r1, [r0]
|
||||
// Init POR
|
||||
ldr r2, =0x50000024 // PORCTL
|
||||
movs r1, #0x5A
|
||||
lsls r1,r1,8
|
||||
adds r1,r1,#0xA5
|
||||
str r1, [r2]
|
||||
// Lock registers
|
||||
movs r1, #0
|
||||
str r1, [r0]
|
||||
|
||||
/* Single section scheme.
|
||||
*
|
||||
* The ranges of copy from/to are specified by following symbols
|
||||
@ -113,12 +131,12 @@ Reset_Handler:
|
||||
ldr r3, = __data_end__
|
||||
|
||||
subs r3, r2
|
||||
ble .L_loop1_done
|
||||
ble .L_loop1_done
|
||||
.L_loop1:
|
||||
subs r3, #4
|
||||
ldr r0, [r1, r3]
|
||||
str r0, [r2, r3]
|
||||
bgt .L_loop1
|
||||
ldr r0, [r1, r3]
|
||||
str r0, [r2, r3]
|
||||
bgt .L_loop1
|
||||
.L_loop1_done:
|
||||
|
||||
/* Single BSS section scheme.
|
||||
@ -135,16 +153,13 @@ Reset_Handler:
|
||||
movs r0, 0
|
||||
|
||||
subs r2, r1
|
||||
ble .L_loop3_done
|
||||
ble .L_loop3_done
|
||||
.L_loop3:
|
||||
subs r2, #4
|
||||
str r0, [r1, r2]
|
||||
bgt .L_loop3
|
||||
str r0, [r1, r2]
|
||||
bgt .L_loop3
|
||||
.L_loop3_done:
|
||||
|
||||
/* There's no SystemInit for NUC123, so no point making a pointless call */
|
||||
// bl SystemInit
|
||||
|
||||
#ifndef __ENTRY
|
||||
#define __ENTRY _entry
|
||||
#endif
|
||||
@ -218,7 +233,7 @@ Default_Handler:
|
||||
SH_DoCommand:
|
||||
|
||||
BKPT 0xAB /* ; Wait ICE or HardFault */
|
||||
//LDR R3, = SH_Return
|
||||
//ldr R3, = SH_Return
|
||||
MOV R4, lr
|
||||
BLX R3 /* ; Call SH_Return. The return value is in R0 */
|
||||
BX R4 /* ; Return value = R0 */
|
||||
|
@ -11,24 +11,23 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "NUC123.h"
|
||||
|
||||
#include "NUC123.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock Variable definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
|
||||
uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */
|
||||
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
|
||||
uint32_t gau32ClkSrcTbl[] = {__HXT, NULL, __HSI, __LIRC, NULL, NULL, NULL, __HIRC};
|
||||
|
||||
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
|
||||
uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */
|
||||
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
|
||||
uint32_t gau32ClkSrcTbl[] = { __HXT, NULL, __HSI, __LIRC, NULL, NULL, NULL, __HIRC };
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock functions
|
||||
This function is used to update the variable SystemCoreClock
|
||||
and must be called whenever the core clock is changed.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
{
|
||||
uint32_t u32Freq, u32ClkSrc;
|
||||
uint32_t u32HclkDiv;
|
||||
@ -38,18 +37,13 @@ void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
|
||||
u32ClkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLK_S_Msk;
|
||||
|
||||
if(u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL)
|
||||
{
|
||||
if (u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL) {
|
||||
/* Use PLL clock */
|
||||
u32Freq = PllClock;
|
||||
}
|
||||
else if(u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL_DIV2)
|
||||
{
|
||||
} else if (u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL_DIV2) {
|
||||
/* Use PLL/2 clock */
|
||||
u32Freq = PllClock >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Use the clock sources directly */
|
||||
u32Freq = gau32ClkSrcTbl[u32ClkSrc];
|
||||
}
|
||||
@ -61,20 +55,3 @@ void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
|
||||
CyclesPerUs = (SystemCoreClock + 500000) / 1000000;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------*/
|
||||
/* Function: SystemInit */
|
||||
/* */
|
||||
/* Parameters: */
|
||||
/* None */
|
||||
/* */
|
||||
/* Returns: */
|
||||
/* None */
|
||||
/* */
|
||||
/* Description: */
|
||||
/* The necessary initialization of system. */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------------------------------------------*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
}
|
||||
|
35
README.md
35
README.md
@ -4,6 +4,41 @@ See [Development](./Development.md) for development information.
|
||||
|
||||
Yes, the code is a mess. I just wanted to get something onto git y'know :).
|
||||
|
||||
## Setup
|
||||
### Installing Firmware
|
||||
- Disconnect the PC cable from the TASOLLER
|
||||
- Hold down the FN2 button, while reconnecting the PC cable
|
||||
- `HOSTMCU` should show as a device
|
||||
- Use `Update V1.1.exe` from official firmware updates to load the firmware
|
||||
|
||||
Currently, Dao CFW is required on the LED board. This is controlled by `LED_FIRMWARE_CFW` in `src/led.h`.
|
||||
|
||||
### Configuring segatools
|
||||
This firmware emulates arcade IO. As such, segatools' emulation should be disabled, by adding the following lines:
|
||||
|
||||
```ini
|
||||
[slider]
|
||||
enable=0
|
||||
[io4]
|
||||
enable=0
|
||||
```
|
||||
|
||||
Ensure no other `[slider]` section exists in the file (or if it does, set `enable=0` there instead).
|
||||
|
||||
The slider **MUST** be assigned to port `COM1`. To do this:
|
||||
|
||||
- Go to `Devices and Printers` in control panel
|
||||
- Double click `TASOLLER`
|
||||
- In the `Hardware` tab, double click `USB Serial Device`
|
||||
- If this already reads `USB Serial Device (COM1)` nothing needs done
|
||||
- Click `Change settings`
|
||||
- Go to `Port Settings` -> `Advanced...`
|
||||
- Under the dropdown for `COM Port Number:` select `COM1`
|
||||
|
||||
If `COM1` is already in use, check what device it is assigned to in Device Manager under `Ports (COM & LPT)`. You may need to enable `View` -> `Show hidden devices`.
|
||||
|
||||
Pre-chusan Chunithm uses IO3. This firmware does not (and unfortunately cannot) support IO3. It is recommended to enable the HID keyboard mode, and continue to use keyboard input for IRs.
|
||||
|
||||
## Configuration
|
||||
Hold FN2 for configuration. It is not the same as stock DAO.
|
||||
|
||||
|
@ -249,7 +249,7 @@ usb_device_descr_t gIO4DeviceDescriptor = {
|
||||
};
|
||||
|
||||
// We have a unified descriptor that covers
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
const usb_desc_config_t Config;
|
||||
|
||||
const usb_desc_iad_t CDC_IAD;
|
||||
|
@ -33,7 +33,7 @@ typedef struct __attribute__((aligned(4), packed)) {
|
||||
|
||||
// Flags
|
||||
union {
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bEnableIO4 : 1;
|
||||
uint8_t bEnableKeyboard : 1;
|
||||
uint8_t bEnableRainbow : 1;
|
||||
|
@ -74,6 +74,7 @@ int _entry(void) {
|
||||
SYS_Bootloader_Check();
|
||||
#endif
|
||||
SYS_ModuleInit();
|
||||
// TODO: Re-lock registers, ideally. Need to check which registers we use where
|
||||
|
||||
FMC_EEPROM_Load();
|
||||
|
||||
|
11
src/psoc.c
11
src/psoc.c
@ -177,8 +177,6 @@ uint16_t PSoC_GetFingerCapacitance(void) {
|
||||
PSoC_Cmd(PSoC_CMD_TX_GET_FINGER_CAP, 0, 0, 1);
|
||||
|
||||
return u16FingerCap;
|
||||
// Swap endian
|
||||
// return (u16FingerCap >> 8) | ((u16FingerCap & 0xff) << 8);
|
||||
}
|
||||
void PSoC_GetDebug(PSoC_CMD_DEBUG u8Cmd, uint8_t* pu8Data, volatile uint8_t* pu8Ready) {
|
||||
pu8PsocGotData = pu8Ready;
|
||||
@ -201,11 +199,6 @@ void PSoC_EnableDebug(uint8_t u8D1, uint8_t u8D2) {
|
||||
|
||||
uint8_t gu8GroundData[32];
|
||||
|
||||
// These are used to uniformly narrow the min/max gap
|
||||
// #define SCALE_OFFSET_MIN 150
|
||||
// #define SCALE_OFFSET_MIN 100
|
||||
// #define SCALE_OFFSET_MAX 450
|
||||
|
||||
void PSoC_PostProcessing(void) {
|
||||
// Process the raw PSoC data to compute our external 0-255 values
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
@ -213,8 +206,8 @@ void PSoC_PostProcessing(void) {
|
||||
|
||||
const uint16_t u16Pad = gu16PSoCDiff[i];
|
||||
|
||||
const uint16_t u16Min = gConfig.u16PSoCScaleMin[i]; // + SCALE_OFFSET_MIN;
|
||||
const uint16_t u16Max = gConfig.u16PSoCScaleMax[i]; // - SCALE_OFFSET_MAX;
|
||||
const uint16_t u16Min = gConfig.u16PSoCScaleMin[i];
|
||||
const uint16_t u16Max = gConfig.u16PSoCScaleMax[i];
|
||||
|
||||
if (u16Pad < u16Min) {
|
||||
gu8GroundData[j] = 0;
|
||||
|
152
src/slider.c
152
src/slider.c
@ -2,11 +2,19 @@
|
||||
|
||||
#define SLIDER_SYNC 0xFF
|
||||
#define SLIDER_MARK 0xFD
|
||||
#define SLIDER_MARKED_SYNC 0xFE
|
||||
#define SLIDER_MARKED_MARK 0xFC
|
||||
|
||||
static uint8_t su8AutoEnabled = 0;
|
||||
static uint8_t su8GotLedData = 0;
|
||||
static uint8_t su8AutoEnabledRaw = 0;
|
||||
static uint8_t su8AutoEnabledByte = 0;
|
||||
static uint32_t su32SinceLastControlled = 0;
|
||||
|
||||
uint8_t gu8GameBrightness = 40; // TODO: Actually make use of this
|
||||
|
||||
static uint16_t su16ByteRawSliderOffset = 0;
|
||||
static uint8_t su8ByteRawSliderShift = 0;
|
||||
|
||||
typedef enum {
|
||||
SLIDER_PARSE_SYNC_WAIT = 0,
|
||||
SLIDER_PARSE_CMD,
|
||||
@ -15,21 +23,8 @@ typedef enum {
|
||||
SLIDER_PARSE_CHECKSUM,
|
||||
} slider_parse_state;
|
||||
|
||||
typedef enum {
|
||||
SLIDER_CMD_AUTO = 0x01,
|
||||
SLIDER_CMD_SET_LED = 0x02,
|
||||
SLIDER_CMD_AUTO_START = 0x03,
|
||||
SLIDER_CMD_AUTO_STOP = 0x04,
|
||||
SLIDER_CMD_RESET = 0x10,
|
||||
SLIDER_CMD_GET_BOARD_INFO = 0xF0,
|
||||
} slider_cmd;
|
||||
|
||||
static const uint8_t su8SliderVersion[32] = {
|
||||
'1', '5', '3', '3', '0', ' ', ' ', ' ', 0xA0,
|
||||
|
||||
'0', '6', '7', '1', '2', 0xFF,
|
||||
|
||||
0x90,
|
||||
static const slider_cmd_Tx_hw_info sSliderHwInfo = {
|
||||
"15330 ", 0xA0, "06712", 0xFF, 0x90, 0, 0,
|
||||
};
|
||||
|
||||
static inline void Slider_Write(uint8_t u8Byte) {
|
||||
@ -39,7 +34,7 @@ static inline void Slider_Write(uint8_t u8Byte) {
|
||||
}
|
||||
USB_VCOM_Write(u8Byte);
|
||||
}
|
||||
static void Slider_Respond(slider_cmd u8SliderCmd, const uint8_t* pu8Packet, uint8_t u8NPacket) {
|
||||
static void Slider_Respond(slider_cmd_Tx u8SliderCmd, const uint8_t* pu8Packet, uint8_t u8NPacket) {
|
||||
uint8_t u8Sum = SLIDER_SYNC + u8SliderCmd + u8NPacket;
|
||||
USB_VCOM_Write(SLIDER_SYNC); // We don't want to escape sync!
|
||||
Slider_Write(u8SliderCmd);
|
||||
@ -52,46 +47,111 @@ static void Slider_Respond(slider_cmd u8SliderCmd, const uint8_t* pu8Packet, uin
|
||||
|
||||
Slider_Write(-u8Sum);
|
||||
}
|
||||
static void Slider_Process(slider_cmd u8SliderCmd, uint8_t* pu8Packet, uint8_t u8NPacket) {
|
||||
static void Slider_Process(slider_cmd_Rx u8SliderCmd, uint8_t* pu8Packet, uint8_t u8NPacket) {
|
||||
switch (u8SliderCmd) {
|
||||
case SLIDER_CMD_RESET:
|
||||
// Hmm? Do we not need to <su8AutoEnabled = 0;> here?
|
||||
Slider_Respond(SLIDER_CMD_RESET, NULL, 0);
|
||||
case SLIDER_CMD_Rx_RESET:
|
||||
// These three weren't present previously, but PSoC firmware suggests they should be
|
||||
// TODO: Validate this against the game!
|
||||
su8AutoEnabled = 0;
|
||||
su8AutoEnabledRaw = 0;
|
||||
su8AutoEnabledByte = 0;
|
||||
// Real firmware can throw a bus exception, but we won't
|
||||
Slider_Respond(SLIDER_CMD_Tx_RESET, NULL, 0);
|
||||
return;
|
||||
case SLIDER_CMD_GET_BOARD_INFO:
|
||||
Slider_Respond(SLIDER_CMD_GET_BOARD_INFO, su8SliderVersion, sizeof su8SliderVersion);
|
||||
case SLIDER_CMD_Rx_HW_INFO:
|
||||
Slider_Respond(SLIDER_CMD_Tx_HW_INFO, (void*)&sSliderHwInfo, sizeof sSliderHwInfo);
|
||||
return;
|
||||
case SLIDER_CMD_Rx_CPU_STATUS:
|
||||
slider_cmd_Tx_cpu_status Status = {
|
||||
{
|
||||
.bGlobalInterrupt = 1,
|
||||
.bWatchdogReset = 0, // Report everything okay
|
||||
.bPowerOnReset = 0, // Cleared in entry0
|
||||
.bSleep = 0, // Obvious
|
||||
.bStop = 0, // Obvious
|
||||
},
|
||||
{
|
||||
.bBootMultiple = 0,
|
||||
.bSlowImo = 0,
|
||||
.bEcoExistsWritten = 1, // Set implicitly in entry0
|
||||
.bEcoExists = 1, // Set in entry0
|
||||
.bSramWatchdog = 0,
|
||||
},
|
||||
};
|
||||
Slider_Respond(SLIDER_CMD_Tx_CPU_STATUS, (void*)&Status, sizeof Status);
|
||||
return;
|
||||
|
||||
case SLIDER_CMD_SET_LED:
|
||||
// TODO: What is the first byte of data? (00h and 28h observed)
|
||||
// Why are there 32 triples?
|
||||
if (u8NPacket == 1 + 0x60) {
|
||||
case SLIDER_CMD_Rx_LED:
|
||||
case SLIDER_CMD_Rx_REPORT_PING_PONG:
|
||||
case SLIDER_CMD_Rx_RAW_PING_PONG:
|
||||
case SLIDER_CMD_Rx_BRAW_PING_PONG:
|
||||
// We have 32 triples here because Chunithm's slider is barely different from Project
|
||||
// Diva's! We only care about the first 31 of them.
|
||||
if (u8NPacket == sizeof(slider_cmd_Rx_led)) {
|
||||
gu8GameBrightness = ((slider_cmd_Rx_led*)pu8Packet)->u8Brightness;
|
||||
|
||||
gbLedDataIsControlledExt = 1;
|
||||
su32SinceLastControlled = 0;
|
||||
memcpy(gu8aControlledExtLedData, &pu8Packet[1], 3 * 32);
|
||||
memcpy(gu8aControlledExtLedData, &((slider_cmd_Rx_led*)pu8Packet)->aBRG, 3 * 32);
|
||||
}
|
||||
// Reprocess this packet as a report request where applicable
|
||||
if (u8SliderCmd == SLIDER_CMD_Rx_REPORT_PING_PONG) {
|
||||
Slider_Process(SLIDER_CMD_Rx_REPORT, pu8Packet, u8NPacket);
|
||||
} else if (u8SliderCmd == SLIDER_CMD_Rx_RAW_PING_PONG) {
|
||||
Slider_Process(SLIDER_CMD_Rx_RAW, pu8Packet, u8NPacket);
|
||||
} else if (u8SliderCmd == SLIDER_CMD_Rx_BRAW_PING_PONG) {
|
||||
Slider_Process(SLIDER_CMD_Rx_BRAW, pu8Packet, u8NPacket);
|
||||
}
|
||||
su8GotLedData = 1;
|
||||
// No response
|
||||
return;
|
||||
|
||||
case SLIDER_CMD_AUTO_START:
|
||||
case SLIDER_CMD_Rx_REPORT:
|
||||
Slider_Respond(SLIDER_CMD_Tx_REPORT, gu8GroundData, sizeof gu8GroundData);
|
||||
return;
|
||||
case SLIDER_CMD_Rx_RAW:
|
||||
// TODO:
|
||||
return;
|
||||
case SLIDER_CMD_Rx_BRAW:
|
||||
// TODO:
|
||||
return;
|
||||
|
||||
case SLIDER_CMD_Rx_REPORT_ENABLE:
|
||||
su8AutoEnabled = 1;
|
||||
su8GotLedData = 1;
|
||||
// No response
|
||||
return;
|
||||
case SLIDER_CMD_AUTO_STOP:
|
||||
case SLIDER_CMD_Rx_RAW_ENABLE:
|
||||
su8AutoEnabledRaw = 1;
|
||||
// No response
|
||||
return;
|
||||
case SLIDER_CMD_Rx_BRAW_ENABLE:
|
||||
su8AutoEnabledByte = 1;
|
||||
// No response
|
||||
return;
|
||||
case SLIDER_CMD_Rx_REPORT_DISABLE:
|
||||
// Purge any Tx buffer from the auto sending
|
||||
if (su8AutoEnabled) USB_VCOM_PurgeTx();
|
||||
if (su8AutoEnabled || su8AutoEnabledRaw || su8AutoEnabledByte) USB_VCOM_PurgeTx();
|
||||
su8AutoEnabled = 0;
|
||||
Slider_Respond(SLIDER_CMD_AUTO_STOP, NULL, 0);
|
||||
su8AutoEnabledRaw = 0;
|
||||
su8AutoEnabledByte = 0;
|
||||
Slider_Respond(SLIDER_CMD_Tx_REPORT_DISABLE, NULL, 0);
|
||||
return;
|
||||
|
||||
// This is an outbound-only command, so we should never see it here!
|
||||
case SLIDER_CMD_AUTO:
|
||||
default:
|
||||
case SLIDER_CMD_Rx_BRAW_SET_OFFSET:
|
||||
su16ByteRawSliderOffset = ((slider_cmd_Rx_braw_set_offset*)pu8Packet)->u16Offset;
|
||||
Slider_Respond(SLIDER_CMD_Tx_BRAW_SET_OFFSET, NULL, 0);
|
||||
return;
|
||||
case SLIDER_CMD_Rx_BRAW_SET_SHIFT:
|
||||
su8ByteRawSliderShift = ((slider_cmd_Rx_braw_set_shift*)pu8Packet)->u8Shift;
|
||||
Slider_Respond(SLIDER_CMD_Tx_BRAW_SET_SHIFT, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void Slider_Exception(uint8_t u8SliderCmd, slider_exception u8Exc) {
|
||||
slider_cmd_TxRx_exception Packet = {
|
||||
u8SliderCmd,
|
||||
u8Exc,
|
||||
};
|
||||
Slider_Respond(SLIDER_CMD_Tx_EXCEPTION, (void*)&Packet, sizeof Packet);
|
||||
}
|
||||
|
||||
void Slider_TickSerial(void) {
|
||||
/**
|
||||
@ -117,12 +177,16 @@ void Slider_TickSerial(void) {
|
||||
while (USB_VCOM_Available()) {
|
||||
uint8_t u8Byte = USB_VCOM_Read();
|
||||
if (u8Byte == SLIDER_MARK) {
|
||||
// Multiple marks in a row get folded down into a single mark
|
||||
u8Mark = 1;
|
||||
continue;
|
||||
} else if (u8Mark) {
|
||||
u8Mark = 0;
|
||||
// TODO: If u8Byte is 0xFD we should technically give up here
|
||||
u8Byte++;
|
||||
// Only unescape if the byte was actually escaped
|
||||
// A mark followed by any other byte is a no-op
|
||||
if (u8Byte == SLIDER_MARKED_SYNC || u8Byte == SLIDER_MARKED_MARK) {
|
||||
u8Byte++;
|
||||
}
|
||||
}
|
||||
|
||||
u8Sum += u8Byte;
|
||||
@ -151,7 +215,11 @@ void Slider_TickSerial(void) {
|
||||
break;
|
||||
case SLIDER_PARSE_CHECKSUM:
|
||||
// Only handle the packet if the sum equaled out
|
||||
if (u8Sum == 0) Slider_Process(u8SliderCmd, u8Packet, u8NPacket);
|
||||
if (u8Sum == 0) {
|
||||
Slider_Process(u8SliderCmd, u8Packet, u8NPacket);
|
||||
} else {
|
||||
Slider_Exception(u8SliderCmd, SLIDER_EXCEPTION_CHECKSUM);
|
||||
}
|
||||
|
||||
su8State = SLIDER_PARSE_SYNC_WAIT;
|
||||
break;
|
||||
@ -172,6 +240,6 @@ void Slider_Tick1ms() {
|
||||
|
||||
u8Counter = 0;
|
||||
|
||||
Slider_Respond(SLIDER_CMD_AUTO, gu8GroundData, sizeof gu8GroundData);
|
||||
Slider_Respond(SLIDER_CMD_Tx_REPORT, gu8GroundData, sizeof gu8GroundData);
|
||||
}
|
||||
}
|
||||
|
136
src/slider.h
136
src/slider.h
@ -1,3 +1,6 @@
|
||||
#pragma once
|
||||
#include "tasoller.h"
|
||||
|
||||
// 16 cells (0-15)
|
||||
#define CELL_0_Msk BIT15
|
||||
#define CELL_1_Msk BIT14
|
||||
@ -49,5 +52,138 @@
|
||||
#define PAD_31_Msk BIT0
|
||||
#define PAD_32_Msk BIT1
|
||||
|
||||
typedef enum {
|
||||
// =========================
|
||||
// Actually used by Chunithm
|
||||
// =========================
|
||||
/* Set LED brightness and BRG values */
|
||||
SLIDER_CMD_Rx_LED = 0x02,
|
||||
|
||||
/* Enable automatic transmission of standard reports */
|
||||
SLIDER_CMD_Rx_REPORT_ENABLE = 0x03,
|
||||
/* Disable automatic tranmission of all reports */
|
||||
SLIDER_CMD_Rx_REPORT_DISABLE = 0x04,
|
||||
|
||||
/* Reset the slider state */
|
||||
SLIDER_CMD_Rx_RESET = 0x10,
|
||||
/* Retrieve hardware information (model number, etc.) */
|
||||
SLIDER_CMD_Rx_HW_INFO = 0xF0,
|
||||
|
||||
// ======
|
||||
// Autism
|
||||
// ======
|
||||
/* Request a single standard report */
|
||||
SLIDER_CMD_Rx_REPORT = 0x01,
|
||||
/* Set LED brightness and BRG values, with a report as the response */
|
||||
SLIDER_CMD_Rx_REPORT_PING_PONG = 0x05,
|
||||
|
||||
/* Request a single raw report */
|
||||
SLIDER_CMD_Rx_RAW = 0x06,
|
||||
/* Enable automatic transmission of raw reports */
|
||||
SLIDER_CMD_Rx_RAW_ENABLE = 0x07,
|
||||
/* Set LED brightness and BRG values, with a raw report as the response */
|
||||
SLIDER_CMD_Rx_RAW_PING_PONG = 0x08,
|
||||
|
||||
/* Set the offset used when producing byte-raw reports */
|
||||
SLIDER_CMD_Rx_BRAW_SET_OFFSET = 0x09,
|
||||
/* Set the shift used when producing byte-raw reports */
|
||||
SLIDER_CMD_Rx_BRAW_SET_SHIFT = 0x0A,
|
||||
/* Request a single byte-raw report */
|
||||
SLIDER_CMD_Rx_BRAW = 0x0B,
|
||||
/* Enable automatic transmission of byte-raw reports */
|
||||
SLIDER_CMD_Rx_BRAW_ENABLE = 0x0C,
|
||||
/* Set LED brightness and BRG values, with a byte-raw report as the response */
|
||||
SLIDER_CMD_Rx_BRAW_PING_PONG = 0x0D,
|
||||
|
||||
/* Request the CPU status registers */
|
||||
SLIDER_CMD_Rx_CPU_STATUS = 0xE0,
|
||||
} slider_cmd_Rx;
|
||||
typedef enum {
|
||||
SLIDER_CMD_Tx_REPORT = 0x01,
|
||||
SLIDER_CMD_Tx_REPORT_DISABLE = 0x04,
|
||||
|
||||
SLIDER_CMD_Tx_RAW = 0x06,
|
||||
|
||||
SLIDER_CMD_Tx_BRAW_SET_OFFSET = 0x09,
|
||||
SLIDER_CMD_Tx_BRAW_SET_SHIFT = 0x0A,
|
||||
SLIDER_CMD_Tx_BRAW = 0x0B,
|
||||
|
||||
SLIDER_CMD_Tx_RESET = 0x10,
|
||||
SLIDER_CMD_Tx_CPU_STATUS = 0xE0,
|
||||
SLIDER_CMD_Tx_EXCEPTION = 0xEE,
|
||||
SLIDER_CMD_Tx_HW_INFO = 0xF0,
|
||||
} slider_cmd_Tx;
|
||||
typedef enum {
|
||||
SLIDER_EXCEPTION_CHECKSUM = 1,
|
||||
SLIDER_EXCEPTION_BUS_ERROR = 2,
|
||||
} slider_exception;
|
||||
/**
|
||||
* If an exception occurs for reasons other than processing a command,
|
||||
* this code is used.
|
||||
* That is, the exception occurs when performing an automatic report.
|
||||
* These will all be bus errors.
|
||||
*/
|
||||
#define SLIDER_EXCEPTION_CTX_GENERIC 0xED
|
||||
|
||||
typedef struct __packed {
|
||||
uint8_t u8Brightness;
|
||||
struct __packed {
|
||||
uint8_t u8B;
|
||||
uint8_t u8R;
|
||||
uint8_t u8G;
|
||||
} aBRG[32];
|
||||
} slider_cmd_Rx_led;
|
||||
typedef struct __packed {
|
||||
uint16_t u16Raw[32];
|
||||
} slider_cmd_Tx_raw;
|
||||
typedef struct __packed {
|
||||
uint16_t u16Offset;
|
||||
} slider_cmd_Rx_braw_set_offset;
|
||||
typedef struct __packed {
|
||||
uint8_t u8Shift;
|
||||
} slider_cmd_Rx_braw_set_shift;
|
||||
typedef struct __packed {
|
||||
uint8_t u8Context;
|
||||
uint8_t u8Error;
|
||||
} slider_cmd_TxRx_exception;
|
||||
typedef struct __packed {
|
||||
char sModel[8];
|
||||
uint8_t u8DeviceClass;
|
||||
char sChipPart[5];
|
||||
uint8_t u8Unk0E;
|
||||
uint8_t u8FwVer;
|
||||
uint8_t u8Unk10;
|
||||
uint8_t u8Unk11;
|
||||
} slider_cmd_Tx_hw_info;
|
||||
typedef struct __packed {
|
||||
union {
|
||||
uint8_t u8Scr0;
|
||||
struct __packed {
|
||||
uint8_t bGlobalInterrupt : 1;
|
||||
uint8_t bRes16 : 1;
|
||||
uint8_t bWatchdogReset : 1;
|
||||
uint8_t bPowerOnReset : 1;
|
||||
uint8_t bSleep : 1;
|
||||
uint8_t bRes12 : 1;
|
||||
uint8_t bRes11 : 1;
|
||||
uint8_t bStop : 1;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t u8Scr1;
|
||||
struct __packed {
|
||||
uint8_t bBootMultiple : 1;
|
||||
uint8_t bRes06 : 1;
|
||||
uint8_t bRes05 : 1;
|
||||
uint8_t bSlowImo : 1;
|
||||
uint8_t bEcoExistsWritten : 1;
|
||||
uint8_t bEcoExists : 1;
|
||||
uint8_t bRes01 : 1;
|
||||
uint8_t bSramWatchdog : 1;
|
||||
};
|
||||
};
|
||||
} slider_cmd_Tx_cpu_status;
|
||||
|
||||
extern uint8_t gu8GameBrightness; // 0~63
|
||||
void Slider_TickSerial(void);
|
||||
void Slider_Tick1ms(void);
|
||||
|
@ -3,6 +3,13 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#elif defined(__GNUC__)
|
||||
#define __packed __attribute__((packed))
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
#define ms *1000
|
||||
#define kHz *1000
|
||||
|
||||
@ -53,7 +60,7 @@ extern volatile uint8_t gu8LEDTx[LED_Tx_BUFFER];
|
||||
#define IO4_PID 0x0021
|
||||
|
||||
#define INCR(x, y) ((x) = (x) < (y) ? (x) + 1 : (y))
|
||||
#define DECR(x, y) ((x) = (x) > (y) ? (x) - 1 : (y))
|
||||
#define DECR(x, y) ((x) = (x) > (y) ? (x)-1 : (y))
|
||||
#define MOD_INCR(x, y) ((x) = (x) == ((y)-1) ? 0 : ((x) + 1))
|
||||
#define MOD_DECR(x, y) ((x) = (x) == 0 ? ((y)-1) : ((x)-1))
|
||||
#define INV(x) ((x) = 1 - (x))
|
||||
@ -78,11 +85,11 @@ enum {
|
||||
#define NUM_AIR 6
|
||||
#define NUM_GROUND 32
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bKeyboard[NUM_FN + NUM_AIR + NUM_GROUND];
|
||||
} hid_report_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint16_t wADC[8];
|
||||
uint16_t wRotary[4];
|
||||
@ -92,12 +99,12 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bUsbStatus;
|
||||
uint8_t bUnique[29];
|
||||
} io4_hid_in_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bCmd;
|
||||
uint8_t bData[62];
|
||||
} io4_hid_out_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint16_t wData[16];
|
||||
} debug_hid_report_t;
|
||||
@ -110,7 +117,7 @@ uint8_t *USBD_HID_GetReport(uint8_t u8ReportId, uint32_t *pu32Size);
|
||||
void USBD_HID_SetReport(volatile uint8_t *pu8EpBuf, uint32_t u32Size);
|
||||
|
||||
// For CDC
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint32_t u32DTERate; // Baud rate
|
||||
uint8_t u8CharFormat; // Stop bit
|
||||
uint8_t u8ParityType; // Parity
|
||||
|
@ -110,96 +110,96 @@ enum {
|
||||
#define GET_LINE_CODING 0x21
|
||||
#define SET_CONTROL_LINE_STATE 0x22
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
union {
|
||||
uint8_t wBytes[6];
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
};
|
||||
|
||||
// Core setup packet types
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bIndex;
|
||||
uint8_t bType;
|
||||
uint16_t wLanguageId;
|
||||
uint16_t wDescriptorLength;
|
||||
} getDescriptor;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wFeature;
|
||||
uint16_t wEp;
|
||||
} clearFeature;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wAddress;
|
||||
} setAddress;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wConfiguration;
|
||||
} setConfiguration;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wFeature;
|
||||
uint16_t wEp;
|
||||
} setFeature;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wAlternate;
|
||||
uint16_t wInterface;
|
||||
} setInterface;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wValue;
|
||||
uint16_t wInterface;
|
||||
} getStatus;
|
||||
|
||||
// USB HID
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bIndex;
|
||||
uint8_t bType;
|
||||
uint16_t wInterfaceNum;
|
||||
uint16_t wDescriptorLength;
|
||||
} hidGetDescriptor;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bReportType;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidGetReport;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bReportType;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidSetReport;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bPad;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidGetIdle;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint8_t bReportId;
|
||||
uint8_t bDuration;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidSetIdle;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wPad;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidGetProtocol;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wProtocol;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} hidSetProtocol;
|
||||
|
||||
// USB CDC
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wValue;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
} getLineCoding;
|
||||
struct __attribute__((packed)) {
|
||||
struct __packed {
|
||||
uint16_t wValue;
|
||||
uint16_t wInterface;
|
||||
uint16_t wLength;
|
||||
@ -207,7 +207,7 @@ typedef struct __attribute__((packed)) {
|
||||
};
|
||||
} usb_setup_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
@ -223,7 +223,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} usb_device_descr_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bFirstInterface;
|
||||
@ -233,7 +233,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bFunctionProtocol;
|
||||
uint8_t iFunction;
|
||||
} usb_desc_iad_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
@ -243,7 +243,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bmAttributes;
|
||||
uint8_t MaxPower;
|
||||
} usb_desc_config_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
@ -254,7 +254,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} usb_desc_interface_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
@ -263,7 +263,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bReportDescriptorType;
|
||||
uint16_t wDescriptorLength;
|
||||
} usb_desc_hid_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
@ -272,27 +272,27 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t bInterval;
|
||||
} usb_desc_endpoint_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint16_t bcdCDC;
|
||||
} usb_desc_cdc_header_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bControlInterface;
|
||||
uint8_t bSubordinateInterface0;
|
||||
} usb_desc_cdc_union_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bmCapabilities;
|
||||
uint8_t bDataInterface;
|
||||
} usb_desc_cdc_call_t;
|
||||
typedef struct __attribute__((packed)) {
|
||||
typedef struct __packed {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include "tasoller.h"
|
||||
|
||||
usb_setup_t g_usbd_SetupPacket;
|
||||
// uint8_t g_usbd_SetupPacket[8] = { 0 };
|
||||
// static const usb_setup_t* p_usbd_SetupPacket = (usb_setup_t*)&g_usbd_SetupPacket;
|
||||
volatile uint8_t g_usbd_RemoteWakeupEn = 0;
|
||||
|
||||
volatile uint8_t *g_usbd_CtrlInPointer = 0;
|
||||
|
@ -85,7 +85,6 @@ void USBD_IRQHandler(void) {
|
||||
}
|
||||
if (u32IntSts & USBD_INTSTS_CDC_CMD) {
|
||||
USBD_CLR_INT_FLAG(USBD_INTSTS_CDC_CMD);
|
||||
// TODO: ACM packets have connect/disconnect?
|
||||
}
|
||||
|
||||
// IO4 HID endpoints
|
||||
|
Loading…
Reference in New Issue
Block a user