Hello, I'm not sure if I've posted in the right category. My goal is to put my Arduino Leonardo board into programming mode using libusb and upload code to it just like in the Arduino IDE. I'm encountering errors while doing this. Please help.
C++ code:
#include <iostream>
#include <libusb.h>
#define YOUR_VENDOR_ID 0x2341
#define YOUR_PRODUCT_ID 0x8036
int main() {
libusb_device** devices;
libusb_context* context = nullptr;
size_t deviceCount;
int rc; // Variable to store error codes
// Initialize Libusb
rc = libusb_init(&context);
if (rc != 0) {
std::cerr << "libusb_init error: " << libusb_error_name(rc) << std::endl;
return -1;
}
// List devices
deviceCount = libusb_get_device_list(context, &devices);
for (size_t i = 0; i < deviceCount; i++) {
libusb_device_descriptor desc;
rc = libusb_get_device_descriptor(devices[i], &desc);
if (rc != 0) {
std::cerr << "libusb_get_device_descriptor error: " << libusb_error_name(rc) << std::endl;
continue;
}
// Identify Atmega32u4 by Vendor ID and Product ID
if (desc.idVendor == YOUR_VENDOR_ID && desc.idProduct == YOUR_PRODUCT_ID) {
std::cout << "Atmega32u4 found!" << std::endl;
libusb_device_handle* handle;
rc = libusb_open(devices[i], &handle);
if (rc != 0) {
std::cerr << "libusb_open error: " << libusb_error_name(rc) << std::endl;
continue;
}
int interface_num = 0; // Correct interface number for AVR programming
// Detach kernel driver if it's active
if (libusb_kernel_driver_active(handle, interface_num)) {
rc = libusb_detach_kernel_driver(handle, interface_num);
if (rc != 0) {
std::cerr << "libusb_detach_kernel_driver error: " << libusb_error_name(rc) << std::endl;
libusb_close(handle);
continue;
}
}
// Request the interface
rc = libusb_claim_interface(handle, interface_num);
if (rc != 0) {
std::cerr << "libusb_claim_interface error: " << libusb_error_name(rc) << std::endl;
libusb_close(handle);
continue;
}
// Send the 'P' command to put Leonardo into programming mode.
unsigned char programModeCommand = 'P';
int transferred;
rc = libusb_bulk_transfer(handle, (2 | LIBUSB_ENDPOINT_OUT), &programModeCommand, 1, &transferred, 5000);
if (rc != 0 || transferred != 1) {
std::cerr << "libusb_bulk_transfer OUT error: " << libusb_error_name(rc) << ", transferred: " << transferred << std::endl;
libusb_release_interface(handle, interface_num);
libusb_attach_kernel_driver(handle, interface_num);
libusb_close(handle);
continue;
}
// Receive the device's response
unsigned char buffer[4];
rc = libusb_bulk_transfer(handle, (2 | LIBUSB_ENDPOINT_IN), buffer, sizeof(buffer), &transferred, 5000);
if (rc != 0 || transferred != sizeof(buffer)) {
std::cerr << "libusb_bulk_transfer IN error: " << libusb_error_name(rc) << ", transferred: " << transferred << std::endl;
libusb_release_interface(handle, interface_num);
libusb_attach_kernel_driver(handle, interface_num);
libusb_close(handle);
continue;
}
if (buffer[0] == '1' && buffer[1] == 'E' && buffer[2] == '9' && buffer[3] == '5') {
std::cerr << "Arduino Leonardo in programming mode!" << std::endl;
}
else {
std::cerr << "Failed to enter programming mode." << std::endl;
}
// Release the interface
libusb_release_interface(handle, interface_num);
libusb_attach_kernel_driver(handle, interface_num);
libusb_close(handle);
}
}
libusb_free_device_list(devices, 1);
libusb_exit(context);
return 0;
}
Output:
Atmega32u4 found!
libusb_detach_kernel_driver error: LIBUSB_ERROR_NOT_SUPPORTED