From 923886efde4b944f906b5bfe120cd3385f47744a Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Fri, 12 Jul 2024 17:18:18 +0100 Subject: [PATCH] waow --- .vscode/c_cpp_properties.json | 10 ++- .vscode/settings.json | 4 +- Development.md | 2 +- NUC123/startup_NUC123.s | 37 ++++++--- NUC123/system_NUC123.c | 41 ++------- README.md | 35 ++++++++ src/descriptors.c | 2 +- src/fmc_user.h | 2 +- src/main.c | 1 + src/psoc.c | 11 +-- src/slider.c | 152 ++++++++++++++++++++++++---------- src/slider.h | 136 ++++++++++++++++++++++++++++++ src/tasoller.h | 19 +++-- src/usb_inc/usb.h | 56 ++++++------- src/usbd_driver.c | 2 - src/usbd_user.c | 1 - 16 files changed, 374 insertions(+), 137 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index bd31aea..d1125b0 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -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 diff --git a/.vscode/settings.json b/.vscode/settings.json index f580eeb..845cb15 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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", ], diff --git a/Development.md b/Development.md index d9b5e60..48273c6 100644 --- a/Development.md +++ b/Development.md @@ -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. diff --git a/NUC123/startup_NUC123.s b/NUC123/startup_NUC123.s index 99df924..aaad46a 100644 --- a/NUC123/startup_NUC123.s +++ b/NUC123/startup_NUC123.s @@ -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 */ diff --git a/NUC123/system_NUC123.c b/NUC123/system_NUC123.c index 7b47694..9673b66 100644 --- a/NUC123/system_NUC123.c +++ b/NUC123/system_NUC123.c @@ -11,24 +11,23 @@ * ******************************************************************************/ #include -#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) -{ -} diff --git a/README.md b/README.md index 3ec4cbd..816d659 100644 --- a/README.md +++ b/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. diff --git a/src/descriptors.c b/src/descriptors.c index 378c0ac..598604d 100644 --- a/src/descriptors.c +++ b/src/descriptors.c @@ -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; diff --git a/src/fmc_user.h b/src/fmc_user.h index 1fa7195..345351b 100644 --- a/src/fmc_user.h +++ b/src/fmc_user.h @@ -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; diff --git a/src/main.c b/src/main.c index e529768..083381c 100644 --- a/src/main.c +++ b/src/main.c @@ -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(); diff --git a/src/psoc.c b/src/psoc.c index 6f94266..c3cebef 100644 --- a/src/psoc.c +++ b/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; diff --git a/src/slider.c b/src/slider.c index 6532493..149e78f 100644 --- a/src/slider.c +++ b/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 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); } } diff --git a/src/slider.h b/src/slider.h index f9bddfc..11bb6b9 100644 --- a/src/slider.h +++ b/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); diff --git a/src/tasoller.h b/src/tasoller.h index 471e94e..0e0049e 100644 --- a/src/tasoller.h +++ b/src/tasoller.h @@ -3,6 +3,13 @@ #include #include +#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 diff --git a/src/usb_inc/usb.h b/src/usb_inc/usb.h index 71e739b..19d90a5 100644 --- a/src/usb_inc/usb.h +++ b/src/usb_inc/usb.h @@ -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; diff --git a/src/usbd_driver.c b/src/usbd_driver.c index 453c47e..8e85458 100644 --- a/src/usbd_driver.c +++ b/src/usbd_driver.c @@ -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; diff --git a/src/usbd_user.c b/src/usbd_user.c index febbd73..f557f6b 100644 --- a/src/usbd_user.c +++ b/src/usbd_user.c @@ -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