This commit is contained in:
Bottersnike 2024-07-12 17:18:18 +01:00
parent 81873aa1ec
commit 923886efde
Signed by: Bottersnike
SSH Key Fingerprint: SHA256:3g0ghwd4dNX1k1RX8qazbiT+3RIYn/daeBevHZVCiU0
16 changed files with 374 additions and 137 deletions

View File

@ -2,9 +2,15 @@
"configurations": [ "configurations": [
{ {
"name": "GCC", "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": [], "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 "version": 4

View File

@ -1,10 +1,12 @@
{ {
"clangd.arguments": ["--query-driver=*arm-none-eabi-*"], "clangd.arguments": ["--query-driver=*arm-none-eabi-*"],
"clangd.fallbackFlags": [ "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/inc",
"-I${workspaceFolder}/NUC123/StdDriver/inc", "-I${workspaceFolder}/NUC123/StdDriver/inc",
"-D__GNUC__", "-D__GNUC__",
"-D__XSTRING(x)=", // Workaround for string.h
"-Wno-pointer-to-int-cast", "-Wno-pointer-to-int-cast",
"-Wno-int-to-pointer-cast", "-Wno-int-to-pointer-cast",
], ],

View File

@ -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. `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.

View File

@ -99,6 +99,24 @@ __Vectors:
Reset_Handler: 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. /* Single section scheme.
* *
* The ranges of copy from/to are specified by following symbols * The ranges of copy from/to are specified by following symbols
@ -142,9 +160,6 @@ Reset_Handler:
bgt .L_loop3 bgt .L_loop3
.L_loop3_done: .L_loop3_done:
/* There's no SystemInit for NUC123, so no point making a pointless call */
// bl SystemInit
#ifndef __ENTRY #ifndef __ENTRY
#define __ENTRY _entry #define __ENTRY _entry
#endif #endif
@ -218,7 +233,7 @@ Default_Handler:
SH_DoCommand: SH_DoCommand:
BKPT 0xAB /* ; Wait ICE or HardFault */ BKPT 0xAB /* ; Wait ICE or HardFault */
//LDR R3, = SH_Return //ldr R3, = SH_Return
MOV R4, lr MOV R4, lr
BLX R3 /* ; Call SH_Return. The return value is in R0 */ BLX R3 /* ; Call SH_Return. The return value is in R0 */
BX R4 /* ; Return value = R0 */ BX R4 /* ; Return value = R0 */

View File

@ -11,8 +11,8 @@
* *
******************************************************************************/ ******************************************************************************/
#include <stdint.h> #include <stdint.h>
#include "NUC123.h"
#include "NUC123.h"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
Clock Variable definitions Clock Variable definitions
@ -20,8 +20,7 @@
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */ uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */ uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */ uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
uint32_t gau32ClkSrcTbl[] = {__HXT, NULL, __HSI, __LIRC, NULL, NULL, NULL, __HIRC}; uint32_t gau32ClkSrcTbl[] = { __HXT, NULL, __HSI, __LIRC, NULL, NULL, NULL, __HIRC };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
Clock functions Clock functions
@ -38,18 +37,13 @@ void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
u32ClkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLK_S_Msk; 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 */ /* Use PLL clock */
u32Freq = PllClock; u32Freq = PllClock;
} } else if (u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL_DIV2) {
else if(u32ClkSrc == CLK_CLKSEL0_HCLK_S_PLL_DIV2)
{
/* Use PLL/2 clock */ /* Use PLL/2 clock */
u32Freq = PllClock >> 1; u32Freq = PllClock >> 1;
} } else {
else
{
/* Use the clock sources directly */ /* Use the clock sources directly */
u32Freq = gau32ClkSrcTbl[u32ClkSrc]; u32Freq = gau32ClkSrcTbl[u32ClkSrc];
} }
@ -61,20 +55,3 @@ void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
CyclesPerUs = (SystemCoreClock + 500000) / 1000000; CyclesPerUs = (SystemCoreClock + 500000) / 1000000;
} }
/*---------------------------------------------------------------------------------------------------------*/
/* Function: SystemInit */
/* */
/* Parameters: */
/* None */
/* */
/* Returns: */
/* None */
/* */
/* Description: */
/* The necessary initialization of system. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void SystemInit(void)
{
}

View File

@ -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 :). 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 ## Configuration
Hold FN2 for configuration. It is not the same as stock DAO. Hold FN2 for configuration. It is not the same as stock DAO.

View File

@ -249,7 +249,7 @@ usb_device_descr_t gIO4DeviceDescriptor = {
}; };
// We have a unified descriptor that covers // We have a unified descriptor that covers
typedef struct __attribute__((packed)) { typedef struct __packed {
const usb_desc_config_t Config; const usb_desc_config_t Config;
const usb_desc_iad_t CDC_IAD; const usb_desc_iad_t CDC_IAD;

View File

@ -33,7 +33,7 @@ typedef struct __attribute__((aligned(4), packed)) {
// Flags // Flags
union { union {
struct __attribute__((packed)) { struct __packed {
uint8_t bEnableIO4 : 1; uint8_t bEnableIO4 : 1;
uint8_t bEnableKeyboard : 1; uint8_t bEnableKeyboard : 1;
uint8_t bEnableRainbow : 1; uint8_t bEnableRainbow : 1;

View File

@ -74,6 +74,7 @@ int _entry(void) {
SYS_Bootloader_Check(); SYS_Bootloader_Check();
#endif #endif
SYS_ModuleInit(); SYS_ModuleInit();
// TODO: Re-lock registers, ideally. Need to check which registers we use where
FMC_EEPROM_Load(); FMC_EEPROM_Load();

View File

@ -177,8 +177,6 @@ uint16_t PSoC_GetFingerCapacitance(void) {
PSoC_Cmd(PSoC_CMD_TX_GET_FINGER_CAP, 0, 0, 1); PSoC_Cmd(PSoC_CMD_TX_GET_FINGER_CAP, 0, 0, 1);
return u16FingerCap; return u16FingerCap;
// Swap endian
// return (u16FingerCap >> 8) | ((u16FingerCap & 0xff) << 8);
} }
void PSoC_GetDebug(PSoC_CMD_DEBUG u8Cmd, uint8_t* pu8Data, volatile uint8_t* pu8Ready) { void PSoC_GetDebug(PSoC_CMD_DEBUG u8Cmd, uint8_t* pu8Data, volatile uint8_t* pu8Ready) {
pu8PsocGotData = pu8Ready; pu8PsocGotData = pu8Ready;
@ -201,11 +199,6 @@ void PSoC_EnableDebug(uint8_t u8D1, uint8_t u8D2) {
uint8_t gu8GroundData[32]; 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) { void PSoC_PostProcessing(void) {
// Process the raw PSoC data to compute our external 0-255 values // Process the raw PSoC data to compute our external 0-255 values
for (uint8_t i = 0; i < 32; i++) { 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 u16Pad = gu16PSoCDiff[i];
const uint16_t u16Min = gConfig.u16PSoCScaleMin[i]; // + SCALE_OFFSET_MIN; const uint16_t u16Min = gConfig.u16PSoCScaleMin[i];
const uint16_t u16Max = gConfig.u16PSoCScaleMax[i]; // - SCALE_OFFSET_MAX; const uint16_t u16Max = gConfig.u16PSoCScaleMax[i];
if (u16Pad < u16Min) { if (u16Pad < u16Min) {
gu8GroundData[j] = 0; gu8GroundData[j] = 0;

View File

@ -2,11 +2,19 @@
#define SLIDER_SYNC 0xFF #define SLIDER_SYNC 0xFF
#define SLIDER_MARK 0xFD #define SLIDER_MARK 0xFD
#define SLIDER_MARKED_SYNC 0xFE
#define SLIDER_MARKED_MARK 0xFC
static uint8_t su8AutoEnabled = 0; 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; 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 { typedef enum {
SLIDER_PARSE_SYNC_WAIT = 0, SLIDER_PARSE_SYNC_WAIT = 0,
SLIDER_PARSE_CMD, SLIDER_PARSE_CMD,
@ -15,21 +23,8 @@ typedef enum {
SLIDER_PARSE_CHECKSUM, SLIDER_PARSE_CHECKSUM,
} slider_parse_state; } slider_parse_state;
typedef enum { static const slider_cmd_Tx_hw_info sSliderHwInfo = {
SLIDER_CMD_AUTO = 0x01, "15330 ", 0xA0, "06712", 0xFF, 0x90, 0, 0,
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 inline void Slider_Write(uint8_t u8Byte) { static inline void Slider_Write(uint8_t u8Byte) {
@ -39,7 +34,7 @@ static inline void Slider_Write(uint8_t u8Byte) {
} }
USB_VCOM_Write(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; uint8_t u8Sum = SLIDER_SYNC + u8SliderCmd + u8NPacket;
USB_VCOM_Write(SLIDER_SYNC); // We don't want to escape sync! USB_VCOM_Write(SLIDER_SYNC); // We don't want to escape sync!
Slider_Write(u8SliderCmd); Slider_Write(u8SliderCmd);
@ -52,46 +47,111 @@ static void Slider_Respond(slider_cmd u8SliderCmd, const uint8_t* pu8Packet, uin
Slider_Write(-u8Sum); 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) { switch (u8SliderCmd) {
case SLIDER_CMD_RESET: case SLIDER_CMD_Rx_RESET:
// Hmm? Do we not need to <su8AutoEnabled = 0;> here? // These three weren't present previously, but PSoC firmware suggests they should be
Slider_Respond(SLIDER_CMD_RESET, NULL, 0); // 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; return;
case SLIDER_CMD_GET_BOARD_INFO: case SLIDER_CMD_Rx_HW_INFO:
Slider_Respond(SLIDER_CMD_GET_BOARD_INFO, su8SliderVersion, sizeof su8SliderVersion); 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; return;
case SLIDER_CMD_SET_LED: case SLIDER_CMD_Rx_LED:
// TODO: What is the first byte of data? (00h and 28h observed) case SLIDER_CMD_Rx_REPORT_PING_PONG:
// Why are there 32 triples? case SLIDER_CMD_Rx_RAW_PING_PONG:
if (u8NPacket == 1 + 0x60) { 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; gbLedDataIsControlledExt = 1;
su32SinceLastControlled = 0; 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; 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; su8AutoEnabled = 1;
su8GotLedData = 1;
// No response // No response
return; 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 // Purge any Tx buffer from the auto sending
if (su8AutoEnabled) USB_VCOM_PurgeTx(); if (su8AutoEnabled || su8AutoEnabledRaw || su8AutoEnabledByte) USB_VCOM_PurgeTx();
su8AutoEnabled = 0; su8AutoEnabled = 0;
Slider_Respond(SLIDER_CMD_AUTO_STOP, NULL, 0); su8AutoEnabledRaw = 0;
su8AutoEnabledByte = 0;
Slider_Respond(SLIDER_CMD_Tx_REPORT_DISABLE, NULL, 0);
return; return;
// This is an outbound-only command, so we should never see it here! case SLIDER_CMD_Rx_BRAW_SET_OFFSET:
case SLIDER_CMD_AUTO: su16ByteRawSliderOffset = ((slider_cmd_Rx_braw_set_offset*)pu8Packet)->u16Offset;
default: 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; 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) { void Slider_TickSerial(void) {
/** /**
@ -117,13 +177,17 @@ void Slider_TickSerial(void) {
while (USB_VCOM_Available()) { while (USB_VCOM_Available()) {
uint8_t u8Byte = USB_VCOM_Read(); uint8_t u8Byte = USB_VCOM_Read();
if (u8Byte == SLIDER_MARK) { if (u8Byte == SLIDER_MARK) {
// Multiple marks in a row get folded down into a single mark
u8Mark = 1; u8Mark = 1;
continue; continue;
} else if (u8Mark) { } else if (u8Mark) {
u8Mark = 0; u8Mark = 0;
// TODO: If u8Byte is 0xFD we should technically give up here // 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++; u8Byte++;
} }
}
u8Sum += u8Byte; u8Sum += u8Byte;
switch (su8State) { switch (su8State) {
@ -151,7 +215,11 @@ void Slider_TickSerial(void) {
break; break;
case SLIDER_PARSE_CHECKSUM: case SLIDER_PARSE_CHECKSUM:
// Only handle the packet if the sum equaled out // 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; su8State = SLIDER_PARSE_SYNC_WAIT;
break; break;
@ -172,6 +240,6 @@ void Slider_Tick1ms() {
u8Counter = 0; u8Counter = 0;
Slider_Respond(SLIDER_CMD_AUTO, gu8GroundData, sizeof gu8GroundData); Slider_Respond(SLIDER_CMD_Tx_REPORT, gu8GroundData, sizeof gu8GroundData);
} }
} }

View File

@ -1,3 +1,6 @@
#pragma once
#include "tasoller.h"
// 16 cells (0-15) // 16 cells (0-15)
#define CELL_0_Msk BIT15 #define CELL_0_Msk BIT15
#define CELL_1_Msk BIT14 #define CELL_1_Msk BIT14
@ -49,5 +52,138 @@
#define PAD_31_Msk BIT0 #define PAD_31_Msk BIT0
#define PAD_32_Msk BIT1 #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_TickSerial(void);
void Slider_Tick1ms(void); void Slider_Tick1ms(void);

View File

@ -3,6 +3,13 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if defined(__CC_ARM)
#elif defined(__GNUC__)
#define __packed __attribute__((packed))
#else
#error Unknown compiler
#endif
#define ms *1000 #define ms *1000
#define kHz *1000 #define kHz *1000
@ -53,7 +60,7 @@ extern volatile uint8_t gu8LEDTx[LED_Tx_BUFFER];
#define IO4_PID 0x0021 #define IO4_PID 0x0021
#define INCR(x, y) ((x) = (x) < (y) ? (x) + 1 : (y)) #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_INCR(x, y) ((x) = (x) == ((y)-1) ? 0 : ((x) + 1))
#define MOD_DECR(x, y) ((x) = (x) == 0 ? ((y)-1) : ((x)-1)) #define MOD_DECR(x, y) ((x) = (x) == 0 ? ((y)-1) : ((x)-1))
#define INV(x) ((x) = 1 - (x)) #define INV(x) ((x) = 1 - (x))
@ -78,11 +85,11 @@ enum {
#define NUM_AIR 6 #define NUM_AIR 6
#define NUM_GROUND 32 #define NUM_GROUND 32
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bKeyboard[NUM_FN + NUM_AIR + NUM_GROUND]; uint8_t bKeyboard[NUM_FN + NUM_AIR + NUM_GROUND];
} hid_report_t; } hid_report_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint16_t wADC[8]; uint16_t wADC[8];
uint16_t wRotary[4]; uint16_t wRotary[4];
@ -92,12 +99,12 @@ typedef struct __attribute__((packed)) {
uint8_t bUsbStatus; uint8_t bUsbStatus;
uint8_t bUnique[29]; uint8_t bUnique[29];
} io4_hid_in_t; } io4_hid_in_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bCmd; uint8_t bCmd;
uint8_t bData[62]; uint8_t bData[62];
} io4_hid_out_t; } io4_hid_out_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint16_t wData[16]; uint16_t wData[16];
} debug_hid_report_t; } 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); void USBD_HID_SetReport(volatile uint8_t *pu8EpBuf, uint32_t u32Size);
// For CDC // For CDC
typedef struct __attribute__((packed)) { typedef struct __packed {
uint32_t u32DTERate; // Baud rate uint32_t u32DTERate; // Baud rate
uint8_t u8CharFormat; // Stop bit uint8_t u8CharFormat; // Stop bit
uint8_t u8ParityType; // Parity uint8_t u8ParityType; // Parity

View File

@ -110,96 +110,96 @@ enum {
#define GET_LINE_CODING 0x21 #define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22 #define SET_CONTROL_LINE_STATE 0x22
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bmRequestType; uint8_t bmRequestType;
uint8_t bRequest; uint8_t bRequest;
union { union {
uint8_t wBytes[6]; uint8_t wBytes[6];
struct __attribute__((packed)) { struct __packed {
uint16_t wValue; uint16_t wValue;
uint16_t wIndex; uint16_t wIndex;
uint16_t wLength; uint16_t wLength;
}; };
// Core setup packet types // Core setup packet types
struct __attribute__((packed)) { struct __packed {
uint8_t bIndex; uint8_t bIndex;
uint8_t bType; uint8_t bType;
uint16_t wLanguageId; uint16_t wLanguageId;
uint16_t wDescriptorLength; uint16_t wDescriptorLength;
} getDescriptor; } getDescriptor;
struct __attribute__((packed)) { struct __packed {
uint16_t wFeature; uint16_t wFeature;
uint16_t wEp; uint16_t wEp;
} clearFeature; } clearFeature;
struct __attribute__((packed)) { struct __packed {
uint16_t wAddress; uint16_t wAddress;
} setAddress; } setAddress;
struct __attribute__((packed)) { struct __packed {
uint16_t wConfiguration; uint16_t wConfiguration;
} setConfiguration; } setConfiguration;
struct __attribute__((packed)) { struct __packed {
uint16_t wFeature; uint16_t wFeature;
uint16_t wEp; uint16_t wEp;
} setFeature; } setFeature;
struct __attribute__((packed)) { struct __packed {
uint16_t wAlternate; uint16_t wAlternate;
uint16_t wInterface; uint16_t wInterface;
} setInterface; } setInterface;
struct __attribute__((packed)) { struct __packed {
uint16_t wValue; uint16_t wValue;
uint16_t wInterface; uint16_t wInterface;
} getStatus; } getStatus;
// USB HID // USB HID
struct __attribute__((packed)) { struct __packed {
uint8_t bIndex; uint8_t bIndex;
uint8_t bType; uint8_t bType;
uint16_t wInterfaceNum; uint16_t wInterfaceNum;
uint16_t wDescriptorLength; uint16_t wDescriptorLength;
} hidGetDescriptor; } hidGetDescriptor;
struct __attribute__((packed)) { struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bReportType; uint8_t bReportType;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidGetReport; } hidGetReport;
struct __attribute__((packed)) { struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bReportType; uint8_t bReportType;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidSetReport; } hidSetReport;
struct __attribute__((packed)) { struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bPad; uint8_t bPad;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidGetIdle; } hidGetIdle;
struct __attribute__((packed)) { struct __packed {
uint8_t bReportId; uint8_t bReportId;
uint8_t bDuration; uint8_t bDuration;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidSetIdle; } hidSetIdle;
struct __attribute__((packed)) { struct __packed {
uint16_t wPad; uint16_t wPad;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidGetProtocol; } hidGetProtocol;
struct __attribute__((packed)) { struct __packed {
uint16_t wProtocol; uint16_t wProtocol;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} hidSetProtocol; } hidSetProtocol;
// USB CDC // USB CDC
struct __attribute__((packed)) { struct __packed {
uint16_t wValue; uint16_t wValue;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
} getLineCoding; } getLineCoding;
struct __attribute__((packed)) { struct __packed {
uint16_t wValue; uint16_t wValue;
uint16_t wInterface; uint16_t wInterface;
uint16_t wLength; uint16_t wLength;
@ -207,7 +207,7 @@ typedef struct __attribute__((packed)) {
}; };
} usb_setup_t; } usb_setup_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t bcdUSB; uint16_t bcdUSB;
@ -223,7 +223,7 @@ typedef struct __attribute__((packed)) {
uint8_t iSerialNumber; uint8_t iSerialNumber;
uint8_t bNumConfigurations; uint8_t bNumConfigurations;
} usb_device_descr_t; } usb_device_descr_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bFirstInterface; uint8_t bFirstInterface;
@ -233,7 +233,7 @@ typedef struct __attribute__((packed)) {
uint8_t bFunctionProtocol; uint8_t bFunctionProtocol;
uint8_t iFunction; uint8_t iFunction;
} usb_desc_iad_t; } usb_desc_iad_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t wTotalLength; uint16_t wTotalLength;
@ -243,7 +243,7 @@ typedef struct __attribute__((packed)) {
uint8_t bmAttributes; uint8_t bmAttributes;
uint8_t MaxPower; uint8_t MaxPower;
} usb_desc_config_t; } usb_desc_config_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bInterfaceNumber; uint8_t bInterfaceNumber;
@ -254,7 +254,7 @@ typedef struct __attribute__((packed)) {
uint8_t bInterfaceProtocol; uint8_t bInterfaceProtocol;
uint8_t iInterface; uint8_t iInterface;
} usb_desc_interface_t; } usb_desc_interface_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t bcdHID; uint16_t bcdHID;
@ -263,7 +263,7 @@ typedef struct __attribute__((packed)) {
uint8_t bReportDescriptorType; uint8_t bReportDescriptorType;
uint16_t wDescriptorLength; uint16_t wDescriptorLength;
} usb_desc_hid_t; } usb_desc_hid_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bEndpointAddress; uint8_t bEndpointAddress;
@ -272,27 +272,27 @@ typedef struct __attribute__((packed)) {
uint8_t bInterval; uint8_t bInterval;
} usb_desc_endpoint_t; } usb_desc_endpoint_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bDescriptorSubtype; uint8_t bDescriptorSubtype;
uint16_t bcdCDC; uint16_t bcdCDC;
} usb_desc_cdc_header_t; } usb_desc_cdc_header_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bDescriptorSubtype; uint8_t bDescriptorSubtype;
uint8_t bControlInterface; uint8_t bControlInterface;
uint8_t bSubordinateInterface0; uint8_t bSubordinateInterface0;
} usb_desc_cdc_union_t; } usb_desc_cdc_union_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bDescriptorSubtype; uint8_t bDescriptorSubtype;
uint8_t bmCapabilities; uint8_t bmCapabilities;
uint8_t bDataInterface; uint8_t bDataInterface;
} usb_desc_cdc_call_t; } usb_desc_cdc_call_t;
typedef struct __attribute__((packed)) { typedef struct __packed {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bDescriptorSubtype; uint8_t bDescriptorSubtype;

View File

@ -1,8 +1,6 @@
#include "tasoller.h" #include "tasoller.h"
usb_setup_t g_usbd_SetupPacket; 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_RemoteWakeupEn = 0;
volatile uint8_t *g_usbd_CtrlInPointer = 0; volatile uint8_t *g_usbd_CtrlInPointer = 0;

View File

@ -85,7 +85,6 @@ void USBD_IRQHandler(void) {
} }
if (u32IntSts & USBD_INTSTS_CDC_CMD) { if (u32IntSts & USBD_INTSTS_CDC_CMD) {
USBD_CLR_INT_FLAG(USBD_INTSTS_CDC_CMD); USBD_CLR_INT_FLAG(USBD_INTSTS_CDC_CMD);
// TODO: ACM packets have connect/disconnect?
} }
// IO4 HID endpoints // IO4 HID endpoints