Last active
July 16, 2024 16:30
-
-
Save GOROman/bed532e395c3320cd21f1157799ff2c6 to your computer and use it in GitHub Desktop.
WCH-LinkE を ARM モードから RISC-V モードに切り替える (Macとかで)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Mac で WCH-LinkE を ARM モードから RISC-V モードに切り替える | |
// | |
// $ brew install libusb | |
// | |
// build: | |
// $ gcc -o wch_link_switch wch_link_switch.c -I/opt/homebrew/include -L /opt/homebrew/lib -lusb-1.0 | |
// | |
// 元ネタ https://github.com/wagiminator/MCU-Flash-Tools/blob/main/rvmode.py | |
#include <libusb-1.0/libusb.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#define CH_VENDOR_ID 0x1A86 | |
#define CH_PRODUCT_ID 0x8010 | |
#define CH_PRODUCT_ID2 0x8012 | |
#define CH_TIMEOUT 5000 | |
void exit_with_error(const char *message) { | |
fprintf(stderr, "%s\n", message); | |
exit(1); | |
} | |
int main() { | |
libusb_device_handle *armlink, *rvlink; | |
libusb_context *context = NULL; | |
int res; | |
res = libusb_init(&context); | |
if (res < 0) { | |
exit_with_error("ERROR: libusb initialization failed"); | |
} | |
libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); | |
printf("Searching for WCH-Link in ARM mode ...\n"); | |
armlink = libusb_open_device_with_vid_pid(context, CH_VENDOR_ID, CH_PRODUCT_ID2); | |
if (armlink == NULL) { | |
libusb_exit(context); | |
exit_with_error("ERROR: No WCH-Link in ARM mode found!"); | |
} | |
printf("SUCCESS: Connected to WCH-Link in ARM mode.\n"); | |
// インターフェースを要求する | |
res = libusb_claim_interface(armlink, 0); | |
if (res != LIBUSB_SUCCESS) { | |
libusb_close(armlink); | |
libusb_exit(context); | |
exit_with_error("ERROR: Failed to claim interface"); | |
} | |
printf("Switching WCH-Link to RISC-V mode ...\n"); | |
unsigned char data[] = {0x81, 0xFF, 0x01, 0x52}; | |
int CH_EP_OUT = 0x02; // ここで正しいエンドポイントアドレスを使用する | |
res = libusb_bulk_transfer(armlink, CH_EP_OUT, data, sizeof(data), NULL, CH_TIMEOUT); | |
if (res != 0) { | |
printf("libusb_bulk_transfer failed: %s\n", libusb_error_name(res)); | |
libusb_release_interface(armlink, 0); | |
libusb_close(armlink); | |
libusb_exit(context); | |
exit_with_error("ERROR: Failed to send data to WCH-Link!"); | |
} | |
libusb_release_interface(armlink, 0); | |
libusb_close(armlink); | |
int counter = 30; | |
while (counter--) { | |
usleep(100000); // 100 ms | |
rvlink = libusb_open_device_with_vid_pid(context, CH_VENDOR_ID, CH_PRODUCT_ID); | |
if (rvlink != NULL) { | |
printf("SUCCESS: WCH-Link is now in RISC-V mode.\n"); | |
libusb_close(rvlink); | |
libusb_exit(context); | |
return 0; | |
} | |
} | |
libusb_exit(context); | |
exit_with_error("ERROR: Switching to RISC-V mode unsuccessful!"); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment