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
@ -113,12 +131,12 @@ Reset_Handler:
ldr r3, = __data_end__ ldr r3, = __data_end__
subs r3, r2 subs r3, r2
ble .L_loop1_done ble .L_loop1_done
.L_loop1: .L_loop1:
subs r3, #4 subs r3, #4
ldr r0, [r1, r3] ldr r0, [r1, r3]
str r0, [r2, r3] str r0, [r2, r3]
bgt .L_loop1 bgt .L_loop1
.L_loop1_done: .L_loop1_done:
/* Single BSS section scheme. /* Single BSS section scheme.
@ -135,16 +153,13 @@ Reset_Handler:
movs r0, 0 movs r0, 0
subs r2, r1 subs r2, r1
ble .L_loop3_done ble .L_loop3_done
.L_loop3: .L_loop3:
subs r2, #4 subs r2, #4
str r0, [r1, r2] str r0, [r1, r2]
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,24 +11,23 @@
* *
******************************************************************************/ ******************************************************************************/
#include <stdint.h> #include <stdint.h>
#include "NUC123.h"
#include "NUC123.h"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
Clock Variable definitions Clock Variable definitions
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
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
This function is used to update the variable SystemCoreClock This function is used to update the variable SystemCoreClock
and must be called whenever the core clock is changed. 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 u32Freq, u32ClkSrc;
uint32_t u32HclkDiv; uint32_t u32HclkDiv;
@ -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,12 +177,16 @@ 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
u8Byte++; // A mark followed by any other byte is a no-op
if (u8Byte == SLIDER_MARKED_SYNC || u8Byte == SLIDER_MARKED_MARK) {
u8Byte++;
}
} }
u8Sum += u8Byte; u8Sum += u8Byte;
@ -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