### Linux Environment Setup Script Source: https://github.com/openwch/arduino_core_ch32/blob/main/README.md This script is used on Linux systems after installing the CH32 Arduino core package. It automatically configures the necessary environment by copying or generating required libraries and rules for the WCH-LINKE programmer. ```bash cd ~/.arduino15/packages/WCH/tools/beforeinstall/1.0.0 ./start.sh ``` -------------------------------- ### Include and Initialize EEPROM Library in Arduino Sketch Source: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/EEPROM/README.md This code snippet demonstrates how to include the EEPROM library and initialize the EEPROM object by calling EEPROM.begin() within the setup() function of an Arduino sketch. This is a prerequisite for using other EEPROM library functions. ```Arduino #include void setup(){ EEPROM.begin(); } void loop(){ } ``` -------------------------------- ### Combine object files and archives into an ELF executable Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe outlines the process of linking object files and archives to create an ELF executable. It specifies linker script, start files, garbage collection sections, map file generation, and library linking. Dependencies include object files and archive file paths. ```makefile recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.extra_flags} -T "{build.system.path}/{build.series}/SRC/Ld/{build.ldscript}" -nostartfiles -Xlinker --gc-sections "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} {build.flags.ldflags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--start-group {object_files} {build.ch_extra_lib} -Wl,--whole-archive "{archive_file_path}" -Wl,--no-whole-archive -lc -Wl,--end-group ``` -------------------------------- ### Hardware Timer Constructor and Setup - Arduino Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes a hardware timer for advanced timing operations such as PWM generation and input capture. The HardwareTimer constructor takes the specific timer instance (e.g., TIM1) as an argument. Requires the Arduino core library. ```cpp #include HardwareTimer *Timer1; volatile uint32_t interruptCount = 0; void timerCallback() { interruptCount++; digitalToggle(PC13); } void setup() { Serial.begin(115200); pinMode(PC13, OUTPUT); // Create timer instance using TIM1 Timer1 = new HardwareTimer(TIM1); // Configure timer to interrupt every 1 second Timer1->setOverflow(1, HERTZ_FORMAT); // 1 Hz = 1 second period Timer1->attachInterrupt(timerCallback); Timer1->resume(); Serial.println("Hardware timer configured for 1 Hz interrupt"); } void loop() { static uint32_t lastCount = 0; if (interruptCount != lastCount) { lastCount = interruptCount; Serial.printf("Timer interrupt %lu triggered\n", interruptCount); } } ``` -------------------------------- ### macOS libusb Installation Source: https://github.com/openwch/arduino_core_ch32/blob/main/README.md On macOS, the 'libusb' library is a prerequisite for using the CH32 core with the Arduino IDE, especially for firmware uploading. This command uses the Homebrew package manager to install it. ```bash brew install libusb ``` -------------------------------- ### Start I2C Transmission to Slave (Arduino Core CH32) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initiates an I2C transmission to a specified slave device address. Data to be sent is queued in a buffer using Wire.write(). The transmission is finalized with Wire.endTransmission(), which returns an error code indicating success or failure. ```cpp #include #define I2C_ADDR 0x50 // EEPROM address void writeEEPROM(uint8_t memAddr, uint8_t data) { Wire.beginTransmission(I2C_ADDR); Wire.write(memAddr); // Send memory address Wire.write(data); // Send data byte uint8_t error = Wire.endTransmission(); if (error == 0) { Serial.println("Write success"); } else { Serial.printf("Write error: %d\n", error); } delay(5); // EEPROM write cycle time } void setup() { Serial.begin(115200); Wire.begin(); // Write sequence of bytes to EEPROM writeEEPROM(0x00, 0xAA); writeEEPROM(0x01, 0x55); writeEEPROM(0x02, 0x12); } void loop() {} ``` -------------------------------- ### Add Arduino Boards Manager URL Source: https://github.com/openwch/arduino_core_ch32/blob/main/README.md This is the URL to add to the Arduino IDE's 'Additional Boards Managers URLs' field to enable the CH32 core support. After adding this, users can search for 'wch' in the board manager to install the package. ```plaintext https://github.com/openwch/board_manager_files/raw/main/package_ch32v_index.json ``` -------------------------------- ### Arduino EEPROM Get Any Data Type Source: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/EEPROM/README.md Retrieves any data type from the EEPROM at a specified address and stores it in a provided variable. Returns a reference to the variable for convenience. ```arduino // Example usage (assuming EEPROM library is included and initialized) int address = 20; long data; EEPROM.get(address, data); // 'data' now holds the value read from EEPROM ``` -------------------------------- ### EEPROM Put/Get Data Structures in C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Illustrates storing and retrieving arbitrary data structures to/from EEPROM using `put()` and `get()` functions. These functions handle the size of the data structure automatically, simplifying the storage of complex data. Requires EEPROM library. ```cpp #include struct Config { uint8_t version; uint16_t sensorCal; float offset; char name[16]; }; void setup() { Serial.begin(115200); EEPROM.begin(); // Write structure to EEPROM Config config = { .version = 1, .sensorCal = 1023, .offset = 2.5, .name = "Sensor-01" }; EEPROM.put(0, config); EEPROM.commit(); Serial.println("Config saved to EEPROM"); // Read structure from EEPROM Config loadedConfig; EEPROM.get(0, loadedConfig); Serial.println("Loaded config:"); Serial.printf(" Version: %d\n", loadedConfig.version); Serial.printf(" Calibration: %d\n", loadedConfig.sensorCal); Serial.printf(" Offset: %.2f\n", loadedConfig.offset); Serial.printf(" Name: %s\n", loadedConfig.name); } void loop() {} ``` -------------------------------- ### Get Milliseconds with millis() - Arduino C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Retrieves the number of milliseconds that have elapsed since the program started. This function is non-blocking and essential for implementing timing-based logic, such as blinking LEDs or creating delays without halting execution. It overflows after approximately 50 days. ```cpp #include unsigned long previousMillis = 0; const long interval = 1000; void setup() { Serial.begin(115200); pinMode(PC13, OUTPUT); } void loop() { unsigned long currentMillis = millis(); // Non-blocking blink without delay() if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; digitalToggle(PC13); Serial.print("Uptime: "); Serial.print(currentMillis / 1000); Serial.println(" seconds"); } } ``` -------------------------------- ### Request Fixed Voltage via USB-PD Sink in C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Requests a specific fixed voltage (5V, 9V, 12V, 15V, or 20V) from a USB-PD power supply. This example uses a button to cycle through voltage requests. It requires the `usbpd_sink.h` library, initialization via `usbpd_sink_init()`, and periodic processing with `usbpd_sink_process()`. ```cpp #include #define BUTTON_PIN A10 uint8_t voltageIndex = 0; Request_voltage_t voltages[] = {REQUEST_5v, REQUEST_9v, REQUEST_12v, REQUEST_15v, REQUEST_20v}; const char* voltageNames[] = {"5V", "9V", "12V", "15V", "20V"}; void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); usbpd_sink_init(); Serial.println("USB-PD Sink Demo"); Serial.println("Press button to cycle through voltages"); } void loop() { usbpd_sink_process(); // Button handling if (digitalRead(BUTTON_PIN) == LOW) { delay(50); // Debounce if (digitalRead(BUTTON_PIN) == LOW) { while (digitalRead(BUTTON_PIN) == LOW); // Wait for release voltageIndex = (voltageIndex + 1) % 5; Serial.printf("Requesting %s\n", voltageNames[voltageIndex]); } } // Request voltage when PD is ready if (usbpd_sink_get_ready()) { if (usbpd_sink_set_request_fixed_voltage(voltages[voltageIndex])) { Serial.printf("Successfully switched to %s\n", voltageNames[voltageIndex]); usbpd_sink_clear_ready(); } else { Serial.printf("Power supply does not support %s\n", voltageNames[voltageIndex]); } } delay(10); } ``` -------------------------------- ### Get Microseconds with micros() - Arduino C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Returns the number of microseconds since the program started. This function provides higher precision timing than millis() and is useful for applications requiring very accurate time measurements, such as pulse detection or high-speed signal processing. It overflows after approximately 70 minutes. ```cpp #include void setup() { Serial.begin(115200); pinMode(PA5, OUTPUT); } void loop() { unsigned long startTime = micros(); // Precise timing measurement digitalWrite(PA5, HIGH); delayMicroseconds(10); digitalWrite(PA5, LOW); unsigned long duration = micros() - startTime; Serial.print("Pulse duration: "); Serial.print(duration); Serial.println(" microseconds"); delay(100); } ``` -------------------------------- ### Set PWM Resolution with analogWriteResolution - Arduino C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Configures the resolution for analogWrite() duty cycle values. The default is 8 bits (0-255). Increasing the resolution, for example to 10 bits (0-1023), allows for finer control over PWM output, which is beneficial for tasks requiring high precision. ```cpp #include #define PWM_PIN PA6 void setup() { pinMode(PWM_PIN, OUTPUT); // Set 10-bit PWM resolution (0-1023) analogWriteResolution(10); } void loop() { // High precision PWM control analogWrite(PWM_PIN, 512); // 50% duty cycle at 10-bit delay(1000); analogWrite(PWM_PIN, 768); // 75% duty cycle at 10-bit delay(1000); analogWrite(PWM_PIN, 256); // 25% duty cycle at 10-bit delay(1000); } ``` -------------------------------- ### Create binary output file (.bin) Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for converting an ELF executable into a binary file. It utilizes the objcopy tool with specific flags for the conversion process. The input is the ELF file, and the output is a .bin file. ```makefile recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" ``` -------------------------------- ### Uploader configuration for WCH-ISP Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Configuration for using WCH-ISP as an uploader. It specifies the path to the WCH-ISP command-line tool and the upload pattern, which includes parameters for verbose output (if enabled) and flashing the ELF file to the target. ```makefile tools.wchisp.path={runtime.tools.wchisp.path}/ tools.wchisp.cmd=wchisp tools.wchisp.upload.params.verbose= tools.wchisp.upload.params.quiet= tools.wchisp.upload.pattern="{path}{cmd}" {upload.verbose} flash "{build.path}/{build.project_name}.elf" ``` -------------------------------- ### Uploader configuration for WCH-LinkE Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Configuration for using WCH-LinkE as an uploader. It specifies the path to the OpenOCD executable, the command to invoke, and the upload pattern including parameters for connecting, halting, programming, verifying, and resetting the target device. ```makefile tools.WCH_linkE.path={runtime.tools.openocd-1.0.0.path}/bin/ tools.WCH_linkE.cmd=openocd tools.WCH_linkE.upload.params.verbose= tools.WCH_linkE.upload.params.quiet= tools.WCH_linkE.upload.config={runtime.tools.openocd.path}/bin/wch-riscv.cfg tools.WCH_linkE.upload.pattern="{path}{cmd}" -f "{upload.config}" -c init -c halt -c "program {{build.path}/{build.project_name}.elf} verify; wlink_reset_resume; exit;" ``` -------------------------------- ### Pre-build: Create build.opt if not exists (Windows, Linux, macOS) Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Ensures that the build.opt file and sketch directory exist before compilation. This is crucial for managing build artifacts and intermediate files. It uses platform-specific commands for creating directories and touch files. ```windows cmd /c if not exist "{build.opt.sourcepath}" mkdir "{build.path}\sketch" & type NUL > "{build.opt.path}" ``` ```linux bash -c "[ -f {build.opt.sourcepath} ] || (mkdir -p {build.path}/sketch && touch {build.opt.path})" ``` ```macosx bash -c "[ -f {build.opt.sourcepath} ] || (mkdir -p {build.path}/sketch && touch {build.opt.path})" ``` -------------------------------- ### Compile C files to object files Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for compiling C source files into object files. It includes compiler path, flags, build information, extra flags, and include paths. The output is an object file. ```makefile recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.info.flags} {compiler.c.extra_flags} {build.extra_flags} {includes} -o "{object_file}" -c "{source_file}" ``` -------------------------------- ### Create archives from object files Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for creating static archives from object files. It uses the archiver tool with specified flags and includes the object file to be archived. ```makefile recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ``` -------------------------------- ### Compile S files to object files Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for compiling assembly (S) source files into object files. It includes compiler path, flags, build information, and specifies the output and source file. ```makefile recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.info.flags} -o "{object_file}" -c "{source_file}" ``` -------------------------------- ### Create hex output file (.hex) Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for converting an ELF executable into a .hex file. It uses the objcopy tool with specific flags for this conversion. The input is the ELF file, and the output is a .hex file. ```makefile recipe.objcopy.hex.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" ``` -------------------------------- ### Debugger general configuration Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt General debugger configuration settings. This includes the path to the executable to be debugged, the toolchain used, its prefix, and path. It also specifies the debug server (OpenOCD) and its configuration details. ```makefile debug.executable={build.path}/{build.project_name}.elf debug.toolchain=gcc debug.toolchain.prefix=riscv-none-embed debug.toolchain.path={compiler.path} debug.server=openocd debug.server.openocd.path={runtime.tools.openocd-1.0.0.path}/bin/openocd debug.server.openocd.scripts_dir={debug.toolchain.path}/scripts debug.server.openocd.script={runtime.tools.openocd.path}/bin/wch-riscv.cfg ``` -------------------------------- ### Initialize EEPROM Emulation - EEPROM::begin - Arduino Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes the EEPROM emulation library, which typically uses flash memory for storage. This function prepares the EEPROM for read and write operations. It does not take any arguments and requires the EEPROM library to be included. ```cpp #include void setup() { Serial.begin(115200); // Initialize EEPROM EEPROM.begin(); Serial.print("EEPROM size: "); Serial.print(EEPROM.length()); Serial.println(" bytes"); } void loop() {} ``` -------------------------------- ### Compile C++ files to object files Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for compiling C++ source files into object files. It includes compiler path, flags, build information, extra flags, and include paths. The output is an object file. ```makefile recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.info.flags} {compiler.cpp.extra_flags} {build.extra_flags} {includes} -o "{object_file}" -c "{source_file}" ``` -------------------------------- ### Compute executable size Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt This recipe defines the command pattern for computing the size of the ELF executable. It uses the size utility and specifies the input ELF file. Regular expressions are provided to parse the output and extract size information for different sections. ```makefile recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=^(?:\.text|\.data|\.rodata)\s+([0-9]+).* recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* ``` -------------------------------- ### CMakeLists.txt: Define Static Library and Link Dependencies Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203C8/CMakeLists.txt Creates a static library 'variant_bin' excluding it from default builds, and links it with 'variant_usage'. It also links 'variant_bin' to the 'variant' interface library. This defines the buildable binary component and its integration with the interface libraries. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203C8.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CMake: Define Static Library and Link to Interface Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6_ADAFRUIT_QTPY/CMakeLists.txt This snippet defines a static library 'variant_bin' with source files and links it to the 'variant_usage' interface library. It also links 'variant_bin' to the main 'variant' interface library. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203G6_QTPY.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CMakeLists.txt: Define Interface Libraries and Dependencies Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203C8/CMakeLists.txt Defines two interface libraries, 'variant' and 'variant_usage', and configures their include directories and library linking. 'variant_usage' includes the current directory, and both are linked against 'base_config' and 'variant_bin' respectively. This sets up the core library structure and dependencies for the project. ```cmake cmake_minimum_required(VERSION 3.21) add_library(variant INTERFACE) add_library(variant_usage INTERFACE) target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) target_link_libraries(variant INTERFACE variant_usage) ``` -------------------------------- ### CH32 Linker and Object Copy Flags Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Specifies flags for the linker and object copy utilities, including options for creating HEX and BIN files, setting EEPROM sections, and managing memory layout. ```makefile compiler.objcopy.eep.flags="-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0" compiler.elf2bin.flags="-O binary" compiler.elf2hex.flags="-O ihex" compiler.objdump.flags="--all-headers --demangle --disassemble -M xw" compiler.c.elf.extra_flags="-Wl,--defsym=__FLASH_SIZE={upload.maximum_size} -Wl,--defsym=__RAM_SIZE={upload.maximum_data_size}" ``` -------------------------------- ### Initialize USB-PD Sink Controller in C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes the USB-PD sink controller for power negotiation with USB-PD power supplies. This function is essential for establishing power communication. Requires the `usbpd_sink.h` library and periodic calls to `usbpd_sink_process()` in the main loop. ```cpp #include void setup() { Serial.begin(115200); // Initialize USB-PD sink usbpd_sink_init(); Serial.println("USB-PD Sink initialized"); Serial.println("Waiting for power source..."); } void loop() { // Must call periodically to handle PD protocol usbpd_sink_process(); if (usbpd_sink_get_ready()) { Serial.println("USB-PD power source connected and ready"); delay(1000); } } ``` -------------------------------- ### CMake: Create Static Library for Variant Bin Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32L10x/CH32L103C8T6/CMakeLists.txt Creates a static library named 'variant_bin' from specified C and C++ source files. This library is excluded from default builds and is linked to 'variant_usage' to provide its functionality to consumers. The library is marked as EXCLUDE_FROM_ALL, meaning it won't be built by default. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V103R8T6.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) ``` -------------------------------- ### Define STATIC Library for Variant Binary Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203C6/CMakeLists.txt This snippet defines a STATIC library named 'variant_bin' which is excluded from all targets by default. It includes source files like 'PeripheralPins.c' and 'variant_CH32V203C6.cpp'. The library links publicly to 'variant_usage' to incorporate its compile-time settings. The main 'variant' library then links to this 'variant_bin' library. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203C6.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### Initialize Serial Port (HardwareSerial::begin) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes serial communication with the specified baud rate and optional configuration for data bits, parity, and stop bits. This function is essential for any serial data exchange. It can be configured with default or custom settings. ```cpp #include void setup() { // Standard initialization at 115200 baud, 8N1 (8 data, no parity, 1 stop) Serial.begin(115200); // Custom configuration: 9 data bits, even parity, 1 stop bit // Serial.begin(115200, SERIAL_9E1); // Wait for serial port to be ready while (!Serial) { ; // Wait for USB serial (not needed for hardware serial) } Serial.println("CH32 Serial Communication Ready"); Serial.print("Configured at "); Serial.print(115200); Serial.println(" baud"); } void loop() { if (Serial.available() > 0) { String input = Serial.readStringUntil('\n'); Serial.print("Received: "); Serial.println(input); } } ``` -------------------------------- ### Initialize SPI Interface (SPIClass::begin) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes the SPI bus, enabling communication with SPI devices. This function can use default pin configurations or allow for custom MISO, MOSI, SCLK, and SSEL pin assignments. It must be called before any SPI read or write operations. ```cpp #include #define CS_PIN PA4 void setup() { Serial.begin(115200); // Initialize with default pins SPI.begin(); // Or specify custom pins: // SPI.setMISO(PA6); // SPI.setMOSI(PA7); // SPI.setSCLK(PA5); // SPI.setSSEL(PA4); // SPI.begin(); pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH); Serial.println("SPI initialized"); } void loop() { // SPI operations here } ``` -------------------------------- ### CMake: Define Interface Libraries and Link Dependencies Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6_ADAFRUIT_QTPY/CMakeLists.txt This snippet defines CMake interface libraries 'variant' and 'variant_usage'. It sets include directories for 'variant_usage' and links 'base_config' to it. The 'variant' library is then linked to 'variant_usage'. ```cmake cmake_minimum_required(VERSION 3.21) add_library(variant INTERFACE) add_library(variant_usage INTERFACE) target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) target_link_libraries(variant INTERFACE variant_usage) ``` -------------------------------- ### CMake: Define Static Library for Variant Bin Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32VM00X/CH32V006K8/CMakeLists.txt Creates a STATIC library 'variant_bin' from C and CPP source files for the CH32V006K8 variant. It's excluded from default builds and linked publicly to 'variant_usage', making its components available to dependents. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V006K8.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CH32 Compiler Warning Flags Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Configures the warning flags for the CH32 compiler. This allows control over the verbosity of compiler warnings, from none to all-inclusive. ```makefile compiler.warning_flags=-Wunused -Wuninitialized compiler.warning_flags.none=-w compiler.warning_flags.default= compiler.warning_flags.more=-Wall compiler.warning_flags.all=-Wall -Wextra ``` -------------------------------- ### Define INTERFACE Libraries for Variant and Usage Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203C6/CMakeLists.txt This snippet defines two INTERFACE libraries, 'variant' and 'variant_usage'. INTERFACE libraries are useful for propagating compile-time information like include directories and link interfaces without producing any output artifacts themselves. 'variant_usage' specifies include directories and links to 'base_config'. 'variant' then links to 'variant_usage'. ```cmake cmake_minimum_required(VERSION 3.21) add_library(variant INTERFACE) add_library(variant_usage INTERFACE) target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) target_link_libraries(variant INTERFACE variant_usage) ``` -------------------------------- ### CH32 C Compiler Flags Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Sets the specific flags used for compiling C source files for the CH32 platform. This includes include paths, optimization levels, debug settings, and warning configurations. ```makefile compiler.ch.extra_include="-I{build.source.path}" "-I{build.core.path}" "-I{build.core.path}/avr/" "-I{build.core.path}/ch32/" "-I{build.core.path}/ch32/lib/" "-I{build.system.path}/{build.series}/USER/" "-I{build.system.path}/{build.series}/SRC/Core/" "-I{build.system.path}/{build.series}/SRC/Debug/" "-I{build.system.path}/{build.series}/SRC/Startup/" "-I{build.system.path}/{build.series}/SRC/Peripheral/inc/" "-I{build.system.path}/{build.series}/SRC/Peripheral/src/" compiler.extra_flags=-march={build.march} -mabi={build.mabi} -msmall-data-limit=8 -msave-restore -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common compiler.c.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std=gnu99 -MMD {compiler.ch.extra_include} ``` -------------------------------- ### Define Variant Binary Library (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6/CMakeLists.txt Defines a static library named 'variant_bin' which is excluded from default builds. It includes source files 'PeripheralPins.c' and 'variant_CH32V203G6.cpp' and links publicly to 'variant_usage', making its dependencies available to targets linking to 'variant_bin'. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203G6.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) ``` -------------------------------- ### CMakeLists.txt Configuration for Arduino Core CH32 Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G8/CMakeLists.txt This snippet demonstrates the CMake configuration for the Arduino Core CH32 project. It utilizes CMake version 3.21 or higher and defines INTERFACE and STATIC libraries to manage build configurations, dependencies, and source files. The configuration ensures proper linking of libraries and include directories for the project. ```cmake cmake_minimum_required(VERSION 3.21) add_library(variant INTERFACE) add_library(variant_usage INTERFACE) target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) target_link_libraries(variant INTERFACE variant_usage) add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203G8.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CH32 C++ Compiler Flags Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Defines the flags for compiling C++ source files for the CH32 platform. It includes settings for C++ standard, exception handling, RTTI, and other compiler options. ```makefile compiler.cpp.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std={compiler.cpp.std} -fno-threadsafe-statics -fno-rtti -fno-exceptions -fno-use-cxa-atexit -MMD {compiler.ch.extra_include} -fpermissive ``` -------------------------------- ### Define Variant Binary Library (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203RB/CMakeLists.txt Creates a static library named 'variant_bin' which is excluded from default builds. It links against 'variant_usage' and includes source files specific to the CH32V203RB variant. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V203RB.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### Define Static Binary Library for Variant Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32X035/CH32X035G8U/CMakeLists.txt This snippet defines a STATIC library named 'variant_bin' which is excluded from all targets by default. It includes specific C and C++ source files and links against the 'variant_usage' library. STATIC libraries are linked into the executable or library they are used with. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32X035G8U.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) ``` -------------------------------- ### Configure Variant Usage Library (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6/CMakeLists.txt Configures the 'variant_usage' interface library by setting its include directories to the current directory ('.'). It also links 'variant_usage' to 'base_config', establishing a dependency for the usage interface. ```cmake target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) ``` -------------------------------- ### Define STATIC Library: variant_bin Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V30x/CH32V307VCT6/CMakeLists.txt Defines a STATIC library named 'variant_bin' which is excluded from the default build. It lists its source files and links it with 'variant_usage'. This library is then linked to the 'variant' INTERFACE library. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V307VCT6.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CH32 RISC-V GCC Compiler Configuration Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Defines the compiler commands and paths for the RISC-V GCC toolchain used for CH32 microcontrollers. It specifies the executables for C, C++, assembler, linker, and other build utilities. ```makefile compiler.path={runtime.tools.riscv-none-embed-gcc-8.2.0.path}/bin/ compiler.S.cmd=riscv-none-embed-gcc compiler.c.cmd=riscv-none-embed-gcc compiler.cpp.cmd=riscv-none-embed-g++ compiler.ar.cmd=riscv-none-embed-ar compiler.c.elf.cmd=riscv-none-embed-g++ compiler.objcopy.cmd=riscv-none-embed-objcopy compiler.elf2hex.cmd=riscv-none-embed-objcopy compiler.objdump.cmd=riscv-none-embed-objdump ``` -------------------------------- ### Define INTERFACE Libraries: variant, variant_usage Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V30x/CH32V307VCT6/CMakeLists.txt Defines two INTERFACE libraries, 'variant' and 'variant_usage'. INTERFACE libraries are used to manage compile-time and link-time dependencies without providing any source code themselves. 'variant_usage' specifies include directories. ```cmake add_library(variant INTERFACE) add_library(variant_usage INTERFACE) target_include_directories(variant_usage INTERFACE . ) target_link_libraries(variant_usage INTERFACE base_config ) target_link_libraries(variant INTERFACE variant_usage) ``` -------------------------------- ### CMake: Link Variant Interface to Variant Bin Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32L10x/CH32L103C8T6/CMakeLists.txt Links the 'variant' interface library to the 'variant_bin' static library. This establishes a dependency, ensuring that any target linking to 'variant' will also inherit the properties and dependencies of 'variant_bin'. ```cmake target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### CH32 Build Information Flags Source: https://github.com/openwch/arduino_core_ch32/blob/main/platform.txt Defines preprocessor macros used during the build process, including Arduino architecture, chip information, board name, and variant definitions. These flags are crucial for conditional compilation. ```makefile build.info.flags="-DARDUINO_ARCH_CH32 -D{build.series} -DARDUINO={runtime.ide.version} -D{build.chip} -DVARIANT_H=\"{build.variant_h}\" {build.usb_flags}" ``` -------------------------------- ### Define Interface Libraries (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6/CMakeLists.txt Defines two interface libraries, 'variant' and 'variant_usage', which serve as abstract targets for managing dependencies and include paths without compiling actual code. These are essential for organizing build configurations in larger projects. ```cmake cmake_minimum_required(VERSION 3.21) add_library(variant INTERFACE) add_library(variant_usage INTERFACE) ``` -------------------------------- ### Link Variant Library (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V20x/CH32V203G6/CMakeLists.txt Links the main 'variant' interface library to 'variant_usage'. This establishes that any target using 'variant' will also inherit the include paths and dependencies defined in 'variant_usage'. ```cmake target_link_libraries(variant INTERFACE variant_usage) ``` -------------------------------- ### Define Static Library and Link Dependencies (CMake) Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V10x/CH32V103R8T6/CMakeLists.txt This snippet defines a static library named 'variant_bin' which is excluded from default builds. It includes source files like 'PeripheralPins.c' and 'variant_CH32V103R8T6.cpp'. The library is linked to 'variant_usage' as a public dependency. This allows the core 'variant' library to then link to 'variant_bin'. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V103R8T6.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) target_link_libraries(variant INTERFACE variant_bin ) ``` -------------------------------- ### Initialize I2C Interface (Arduino Core CH32) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Initializes the I2C interface, allowing the microcontroller to act as either a master or a slave device. Default SDA and SCL pins are used, defined by the specific board variant. An optional function to set the I2C clock frequency is also available. ```cpp #include void setup() { Serial.begin(115200); // Initialize as I2C master Wire.begin(); // Or initialize as slave with address 0x08: // Wire.begin(0x08); // Optional: set I2C clock frequency to 400kHz (Fast Mode) // Wire.setClock(400000); Serial.println("I2C initialized"); } void loop() { // I2C operations here } ``` -------------------------------- ### CMake: Define Static Library for CH32 Variant Binaries Source: https://github.com/openwch/arduino_core_ch32/blob/main/variants/CH32V00x/CH32V003F4/CMakeLists.txt This snippet defines a static library 'variant_bin' which is excluded from all targets by default. It compiles C and C++ source files and links the 'variant_usage' library to it. ```cmake add_library(variant_bin STATIC EXCLUDE_FROM_ALL PeripheralPins.c variant_CH32V003F4.cpp ) target_link_libraries(variant_bin PUBLIC variant_usage) ``` -------------------------------- ### Arduino EEPROM Put Any Data Type Source: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/EEPROM/README.md Writes any data type to the EEPROM at a specified address. Requires EEPROM.commit() to save changes. Returns a reference to the variable for convenience. ```arduino // Example usage (assuming EEPROM library is included and initialized) int address = 30; float value = 3.14; EEPROM.put(address, value); EEPROM.commit(); // Save the changes ``` -------------------------------- ### Arduino EEPROM Subscript Operator for Direct Access Source: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/EEPROM/README.md Allows direct reading and writing of EEPROM RAM elements using array-like syntax. Changes must be committed using EEPROM.commit(). Returns a reference to the EEPROM RAM element. ```arduino uint8_t val; //Read first EEPROM RAM element. val = EEPROM[ 0 ]; //Write first EEPROM RAM element. EEPROM[ 0 ] = val; //Compare contents if( val == EEPROM[ 0 ] ){ //Do something... } ``` -------------------------------- ### Formatted Print to Serial (HardwareSerial::printf) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Prints a formatted string to the serial port using printf-style formatting. This function allows for complex output with mixed data types, controlling precision, alignment, and type representation. It's useful for creating structured log messages or reports. ```cpp #include void setup() { Serial.begin(115200); Serial.printf("CH32 Chip ID: 0x%08X\n", DBGMCU_GetDEVID()); } void loop() { static int counter = 0; float temperature = 25.5 + (counter % 10) * 0.1; // Formatted output with mixed types Serial.printf("Count: %04d | Temp: %.2f°C | Status: %s\n", counter, temperature, (counter % 2) ? "Active" : "Idle"); counter++; delay(1000); } ``` -------------------------------- ### Configure Pin Direction and Pull Resistors (Arduino C++) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Configures a GPIO pin as input, output, or input with pull-up/pull-down resistors. Supports standard Arduino modes and CH32-specific INPUT_PULLDOWN. ```cpp #include void setup() { // Configure pin PC13 as output for LED pinMode(PC13, OUTPUT); // Configure pin PA0 as input with internal pull-up pinMode(PA0, INPUT_PULLUP); // Configure pin PA1 as input with pull-down (CH32-specific) pinMode(PA1, INPUT_PULLDOWN); // Configure pin PA2 as standard high-impedance input pinMode(PA2, INPUT); } void loop() { // Pin modes are persistent until changed digitalWrite(PC13, HIGH); delay(500); digitalWrite(PC13, LOW); delay(500); } ``` -------------------------------- ### Configure SPI Transaction Settings (Arduino Core CH32) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Sets SPI clock speed, bit order (MSBFIRST/LSBFIRST), and data mode (SPI_MODE0-3). This function must be paired with SPI.endTransaction() to complete the configuration. It is essential for preparing the SPI bus for data transfer operations. ```cpp #include #define CS_PIN PA4 SPISettings spiSettings(1000000, MSBFIRST, SPI_MODE0); // 1MHz, MSB first, mode 0 void setup() { Serial.begin(115200); SPI.begin(); pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH); } uint8_t spiTransfer(uint8_t data) { SPI.beginTransaction(spiSettings); digitalWrite(CS_PIN, LOW); uint8_t result = SPI.transfer(data); digitalWrite(CS_PIN, HIGH); SPI.endTransaction(); return result; } void loop() { uint8_t response = spiTransfer(0x3C); // Send command, receive response Serial.printf("SPI Response: 0x%02X\n", response); delay(1000); } ``` -------------------------------- ### EEPROM Read/Write Individual Bytes in C++ Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Demonstrates reading and writing individual bytes to the EEPROM. Write operations require a subsequent call to `commit()` to persist changes to flash memory. This is useful for storing small configuration values. ```cpp #include void setup() { Serial.begin(115200); EEPROM.begin(); // Write configuration data EEPROM.write(0, 0xAA); // Magic byte EEPROM.write(1, 100); // Setting 1 EEPROM.write(2, 200); // Setting 2 // Commit changes to flash if (EEPROM.commit()) { Serial.println("EEPROM written successfully"); } else { Serial.println("EEPROM write failed"); } // Read back data uint8_t magic = EEPROM.read(0); uint8_t setting1 = EEPROM.read(1); uint8_t setting2 = EEPROM.read(2); Serial.printf("Magic: 0x%02X, Settings: %d, %d\n", magic, setting1, setting2); } void loop() {} ``` -------------------------------- ### Arduino EEPROM Read Option Bytes CH32 Source: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/EEPROM/README.md Reads the user option bytes information block, specifically data0 and data1 bytes, which are stored in the user select word storage area. These bytes are available even before EEPROM.begin() and are copied to EEPROM addresses 0 and 1 after EEPROM.begin(). Returns a uint32_t value containing data0, data1, and their inversed values. ```arduino // Example usage (assuming EEPROM library is included) // This can be called even before EEPROM.begin() uint32_t optionBytesData = EEPROM.ReadOptionBytes(); // Process optionBytesData to extract data0 and data1 bytes ``` -------------------------------- ### Print Data to Serial (HardwareSerial::print/println) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Prints data to the serial port in human-readable ASCII text. The `println` function appends a newline character after printing. This function supports printing various data types and can format numbers to a specified number of decimal places or in different bases (DEC, HEX, BIN). ```cpp #include void setup() { Serial.begin(115200); } void loop() { int sensorValue = analogRead(A0); float voltage = sensorValue * 3.3 / 1023.0; // Print without newline Serial.print("Sensor: "); Serial.print(sensorValue); Serial.print(" | Voltage: "); Serial.print(voltage, 3); // 3 decimal places Serial.println(" V"); // println adds newline // Print in different formats Serial.print("DEC: "); Serial.println(255, DEC); // 255 Serial.print("HEX: "); Serial.println(255, HEX); // ff Serial.print("BIN: "); Serial.println(255, BIN); // 11111111 delay(1000); } ``` -------------------------------- ### Scan I2C Bus for Devices (Arduino Core CH32) Source: https://context7.com/openwch/arduino_core_ch32/llms.txt Scans the I2C bus by attempting communication with all possible slave addresses (7-bit, from 8 to 127). It reports the addresses of any devices found, which is useful for identifying connected peripherals or debugging I2C communication issues. ```cpp #include void setup() { Serial.begin(115200); while (!Serial) { ; // Wait for serial ready } Serial.println("I2C Scanner"); Wire.begin(); } void loop() { byte error, address; int deviceCount = 0; Serial.println("Scanning..."); for (address = 8; address < 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("Found device at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.printf(" (%d)\n", address); deviceCount++; delay(1); } } if (deviceCount == 0) { Serial.println("No I2C devices found"); } else { Serial.printf("Found %d device(s)\n", deviceCount); } delay(5000); // Wait 5 seconds before next scan } ```