Compare commits

..
12 Commits
Author SHA1 Message Date
Earle F. Philhower, III 0550fe75b2 Massively reduce generated code and RAM size (#137)
Older builds included C++ locale information in RAM/flash as well as a
bunch of exception code which can't get called since they're not enabled.

Remove them by adjusting final link command and not instantiating them
in main.cpp in the first place.

Blink went from:
> Sketch uses 215604 bytes (10%) of program storage space. Maximum is 2093056 bytes.
> Global variables use 18152 bytes (6%) of dynamic memory, leaving 243992 bytes for local variables. Maximum is 262144 bytes.

To:
> Sketch uses 56112 bytes (5%) of program storage space. Maximum is 1044480 bytes.
> Global variables use 12152 bytes (4%) of dynamic memory, leaving 249992 bytes for local variables. Maximum is 262144 bytes.

For a savings of **155KB of flash** and **6KB of RAM**
2021-05-16 02:14:58 -07:00
Earle F. Philhower, III ef6024911a Merge branch 'master' of https://github.com/earlephilhower/arduino-pico 2021-05-15 16:29:46 -07:00
Earle F. Philhower, III 78c021aadf Add forgotten USB header 2021-05-15 16:29:32 -07:00
Earle F. Philhower, III fdcfe549cb Add forgotten USB header 2021-05-15 16:29:08 -07:00
Earle F. Philhower, III a64339b195 Update README.md 2021-05-15 16:19:55 -07:00
Earle F. Philhower, III 9725155f25 Fix SPI default pinouts to SPI0, not SPI1 pins (#135)
Should fix #134 .  The SPI pin macros were set using the SPI1 set, not
the SPI0 set of pins it should have been using.
2021-05-15 16:13:11 -07:00
Earle F. Philhower, III cdc2831103 Update install.rst 2021-05-15 12:24:14 -07:00
Earle F. Philhower, III d3c5039c2f Clean up USB includes and naming 2021-05-14 12:08:00 -07:00
Earle F. Philhower, III 13f4be33bc Update index.rst 2021-05-14 08:18:33 -07:00
Earle F. Philhower, III 6cf90add8c Add basic USB documentation 2021-05-14 07:58:32 -07:00
Earle F. Philhower, III 2723a6e71d Update README.md 2021-05-14 07:51:31 -07:00
Earle F. Philhower, III 4a8ac3d902 Add support for shared USB Serial, Keyboard, Mouse (#132)
Use a shared infrastructure based on TinyUSB, allow users to use sketches
with ported Arduino Keyboard and Mouse libraries.
2021-05-13 19:20:24 -07:00
16 changed files with 546 additions and 154 deletions
+6
View File
@@ -16,3 +16,9 @@
[submodule "pico-extras"]
path = pico-extras
url = https://github.com/raspberrypi/pico-extras.git
[submodule "libraries/Keyboard"]
path = libraries/Keyboard
url = https://github.com/earlephilhower/Keyboard
[submodule "libraries/Mouse"]
path = libraries/Mouse
url = https://github.com/earlephilhower/Mouse
+5 -8
View File
@@ -2,14 +2,10 @@
Raspberry Pi Pico Arduino core, for all RP2040 boards
This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem.
This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem. It uses the bare Raspberry Pi Pico SDK and a custom GCC 10.2/Newlib 4.0 toolchain.
It uses a custom toolset with GCC 10.2 and Newlib 4.0.0, not depending on system-installed prerequisites. https://github.com/earlephilhower/pico-quick-toolchain
There is automated discovery of boards in bootloader mode, so they show up in the IDE, and the upload command works using the Microsoft UF2 tool (included).
# Detailed Documentation
Refer to the examples and https://arduino-pico.readthedocs.io/en/latest/ for more detailed usage information.
# Documentation
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
# Installing via Arduino Boards Manager
**Windows Users**: Please do not use the Windows Store version of the actual Arduino application
@@ -98,6 +94,7 @@ The installed tools include a version of OpenOCD (in the pqt-openocd directory)
# Status of Port
Relatively stable and very functional, but bug reports and PRs always accepted.
* USB Keyboard and Mouse emulation
* Multicore support (setup1() and loop1())
* digitalWrite/Read
* shiftIn/Out
@@ -135,7 +132,7 @@ If you want to contribute or have bugfixes, drop me a note at <earlephilhower@ya
* The [Arduino IDE and ArduinoCore-API](https://arduino.cc) are developed and maintained by the Arduino team. The IDE is licensed under GPL.
* The [RP2040 GCC-based toolchain](https://github.com/earlephilhower/pico-quick-toolchain) is licensed under under the GPL.
* The [Pico-SDK](https://github.com/raspberrypi/pico-sdk) and [Pico-Extras](https://github.com/raspberrypi/pico-extras) are by Raspberry Pi (Trading) Ltd and licensed under the BSD 3-Clause license.
* [Arduino-Pico](https://github.com/earlephilhower/arduino-pico) core files are licenses under the LGPL.
* [Arduino-Pico](https://github.com/earlephilhower/arduino-pico) core files are licensed under the LGPL.
* [LittleFS](https://github.com/ARMmbed/littlefs) library written by ARM Limited and released under the [BSD 3-clause license](https://github.com/ARMmbed/littlefs/blob/master/LICENSE.md).
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporation and licensed under the MIT license.
* Some filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
+319
View File
@@ -0,0 +1,319 @@
/*
* Shared USB for the Raspberry Pi Pico RP2040
* Allows for multiple endpoints to share the USB controller
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include "CoreMutex.h"
#include "RP2040USB.h"
#include "tusb.h"
#include "class/hid/hid_device.h"
#include "class/audio/audio.h"
#include "class/midi/midi.h"
#include "pico/time.h"
#include "hardware/irq.h"
#include "pico/mutex.h"
#include "pico/unique_id.h"
// Big, global USB mutex, shared with all USB devices to make sure we don't
// have multiple cores updating the TUSB state in parallel
mutex_t __usb_mutex;
// USB processing will be a periodic timer task
#define USB_TASK_INTERVAL 1000
#define USB_TASK_IRQ 31
// USB VID/PID (note that PID can change depending on the add'l interfaces)
#define USBD_VID (0x2E8A) // Raspberry Pi
#ifdef SERIALUSB_PID
#define USBD_PID (SERIALUSB_PID)
#else
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define USBD_MAX_POWER_MA (250)
#define USBD_ITF_CDC (0) // needs 2 interfaces
#define USBD_ITF_MAX (2)
#define USBD_CDC_EP_CMD (0x81)
#define USBD_CDC_EP_OUT (0x02)
#define USBD_CDC_EP_IN (0x82)
#define USBD_CDC_CMD_MAX_SIZE (8)
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
#define USBD_STR_0 (0x00)
#define USBD_STR_MANUF (0x01)
#define USBD_STR_PRODUCT (0x02)
#define USBD_STR_SERIAL (0x03)
#define USBD_STR_CDC (0x04)
#define EPNUM_HID 0x83
#define EPNUM_MIDI 0x01
const uint8_t *tud_descriptor_device_cb(void) {
static tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_CDC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USBD_VID,
.idProduct = USBD_PID,
.bcdDevice = 0x0100,
.iManufacturer = USBD_STR_MANUF,
.iProduct = USBD_STR_PRODUCT,
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1
};
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallMIDI) {
// Can use as-is, this is the default USB case
return (const uint8_t *)&usbd_desc_device;
}
// Need a multi-endpoint config which will require changing the PID to help Windows not barf
if (__USBInstallKeyboard) {
usbd_desc_device.idProduct |= 0x8000;
}
if (__USBInstallMouse) {
usbd_desc_device.idProduct |= 0x4000;
}
if (__USBInstallMIDI) {
usbd_desc_device.idProduct |= 0x2000;
}
// Set the device class to 0 to indicate multiple device classes
usbd_desc_device.bDeviceClass = 0;
usbd_desc_device.bDeviceSubClass = 0;
usbd_desc_device.bDeviceProtocol = 0;
return (const uint8_t *)&usbd_desc_device;
}
int __USBGetKeyboardReportID() {
return 1;
}
int __USBGetMouseReportID() {
return __USBInstallKeyboard ? 2 : 1;
}
static uint8_t *GetDescHIDReport(int *len) {
if (__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) )
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
} else if (__USBInstallKeyboard && ! __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) )
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
} else { // if (!__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE( HID_REPORT_ID(1) )
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
}
}
// Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(void)
{
return GetDescHIDReport(nullptr);
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
int len = 0;
static uint8_t *usbd_desc_cfg;
if (!usbd_desc_cfg) {
bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMIDI ? 2 : 0);
static uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE)
};
int hid_report_len;
GetDescHIDReport(&hid_report_len);
uint8_t hid_itf = __USBInstallSerial ? 2 : 0;
static uint8_t hid_desc[TUD_HID_DESC_LEN] = {
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
};
uint8_t midi_itf = hid_itf + (hasHID ? 1 : 0);
static uint8_t midi_desc[TUD_MIDI_DESC_LEN] = {
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(midi_itf, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64)
};
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMIDI ? sizeof(midi_desc) : 0);
static uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, interface_count, USBD_STR_0, usbd_desc_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA)
};
// Combine to one descriptor
usbd_desc_cfg = (uint8_t *)malloc(usbd_desc_len);
bzero(usbd_desc_cfg, usbd_desc_len);
uint8_t *ptr = usbd_desc_cfg;
memcpy(ptr, tud_cfg_desc, sizeof(tud_cfg_desc));
ptr += sizeof(tud_cfg_desc);
if (__USBInstallSerial) {
memcpy(ptr, cdc_desc, sizeof(cdc_desc));
ptr += sizeof(cdc_desc);
}
if (hasHID) {
memcpy(ptr, hid_desc, sizeof(hid_desc));
ptr += sizeof(hid_desc);
}
if (__USBInstallMIDI) {
memcpy(ptr, midi_desc, sizeof(midi_desc));
}
}
return usbd_desc_cfg;
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
static char idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
static const char *const usbd_desc_str[] = {
[USBD_STR_0] = "",
[USBD_STR_MANUF] = "Raspberry Pi",
[USBD_STR_PRODUCT] = "PicoArduino",
[USBD_STR_SERIAL] = idString,
[USBD_STR_CDC] = "Board CDC",
};
if (!idString[0]) {
// Get ID string into human readable serial number on the first pass
pico_unique_board_id_t id;
pico_get_unique_board_id(&id);
idString[0] = 0;
for (auto i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++) {
char hx[3];
sprintf(hx, "%02X", id.id[i]);
strcat(idString, hx);
}
}
uint8_t len;
if (index == 0) {
desc_str[1] = 0x0409; // supported language is English
len = 1;
} else {
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
return NULL;
}
const char *str = usbd_desc_str[index];
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
desc_str[1 + len] = str[len];
}
}
// first byte is length (including header), second byte is string type
desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2);
return desc_str;
}
static void usb_irq() {
// if the mutex is already owned, then we are in user code
// in this file which will do a tud_task itself, so we'll just do nothing
// until the next tick; we won't starve
if (mutex_try_enter(&__usb_mutex, NULL)) {
tud_task();
mutex_exit(&__usb_mutex);
}
}
static int64_t timer_task(__unused alarm_id_t id, __unused void *user_data) {
irq_set_pending(USB_TASK_IRQ);
return USB_TASK_INTERVAL;
}
void __USBStart() {
if (tusb_inited()) {
// Already called
return;
}
mutex_init(&__usb_mutex);
tusb_init();
irq_set_exclusive_handler(USB_TASK_IRQ, usb_irq);
irq_set_enabled(USB_TASK_IRQ, true);
add_alarm_in_us(USB_TASK_INTERVAL, timer_task, NULL, true);
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
// TODO not Implemented
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
}
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}
+39
View File
@@ -0,0 +1,39 @@
/*
* Shared USB for the Raspberry Pi Pico RP2040
* Allows for multiple endpoints to share the USB controller
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pico/mutex.h"
// Weak function definitions for each type of endpoint
extern void __USBInstallSerial() __attribute__((weak));
extern void __USBInstallKeyboard() __attribute__((weak));
extern void __USBInstallMouse() __attribute__((weak));
extern void __USBInstallMIDI() __attribute__((weak));
// Big, global USB mutex, shared with all USB devices to make sure we don't
// have multiple cores updating the TUSB state in parallel
extern mutex_t __usb_mutex;
// HID report ID inquiry (report ID will vary depending on the number/type of other HID)
int __USBGetKeyboardReportID();
int __USBGetMouseReportID();
// Called by main() to init the USB HW/SW.
void __USBStart();
+13 -139
View File
@@ -32,6 +32,11 @@
#include "hardware/watchdog.h"
#include "pico/unique_id.h"
#ifndef DISABLE_USB_SERIAL
// Ensure we are installed in the USB chain
void __USBInstallSerial() { /* noop */ }
#endif
// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
@@ -39,121 +44,8 @@
// HardwareSerial instance if the user doesn't also refer to it.
extern void serialEvent() __attribute__((weak));
#define PICO_STDIO_USB_TASK_INTERVAL_US 1000
#define PICO_STDIO_USB_LOW_PRIORITY_IRQ 31
#define USBD_VID (0x2E8A) // Raspberry Pi
#ifdef SERIALUSB_PID
#define USBD_PID (SERIALUSB_PID)
#else
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define USBD_MAX_POWER_MA (250)
#define USBD_ITF_CDC (0) // needs 2 interfaces
#define USBD_ITF_MAX (2)
#define USBD_CDC_EP_CMD (0x81)
#define USBD_CDC_EP_OUT (0x02)
#define USBD_CDC_EP_IN (0x82)
#define USBD_CDC_CMD_MAX_SIZE (8)
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
#define USBD_STR_0 (0x00)
#define USBD_STR_MANUF (0x01)
#define USBD_STR_PRODUCT (0x02)
#define USBD_STR_SERIAL (0x03)
#define USBD_STR_CDC (0x04)
// Note: descriptors returned from callbacks must exist long enough for transfer to complete
static const tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_CDC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USBD_VID,
.idProduct = USBD_PID,
.bcdDevice = 0x0100,
.iManufacturer = USBD_STR_MANUF,
.iProduct = USBD_STR_PRODUCT,
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1,
};
static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = {
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA),
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
};
static char _idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
static const char *const usbd_desc_str[] = {
[USBD_STR_0] = "",
[USBD_STR_MANUF] = "Raspberry Pi",
[USBD_STR_PRODUCT] = "PicoArduino",
[USBD_STR_SERIAL] = _idString,
[USBD_STR_CDC] = "Board CDC",
};
const uint8_t *tud_descriptor_device_cb(void) {
return (const uint8_t *)&usbd_desc_device;
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
return usbd_desc_cfg;
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
uint8_t len;
if (index == 0) {
desc_str[1] = 0x0409; // supported language is English
len = 1;
} else {
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
return NULL;
}
const char *str = usbd_desc_str[index];
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
desc_str[1 + len] = str[len];
}
}
// first byte is length (including header), second byte is string type
desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2);
return desc_str;
}
static mutex_t usb_mutex;
static void low_priority_worker_irq() {
// if the mutex is already owned, then we are in user code
// in this file which will do a tud_task itself, so we'll just do nothing
// until the next tick; we won't starve
if (mutex_try_enter(&usb_mutex, NULL)) {
tud_task();
mutex_exit(&usb_mutex);
}
}
static int64_t timer_task(__unused alarm_id_t id, __unused void *user_data) {
irq_set_pending(PICO_STDIO_USB_LOW_PRIORITY_IRQ);
return PICO_STDIO_USB_TASK_INTERVAL_US;
}
extern mutex_t __usb_mutex;
void SerialUSB::begin(unsigned long baud) {
(void) baud; //ignored
@@ -162,24 +54,6 @@ void SerialUSB::begin(unsigned long baud) {
return;
}
// Get ID string into human readable serial number
pico_unique_board_id_t id;
pico_get_unique_board_id(&id);
_idString[0] = 0;
for (auto i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++) {
char hx[3];
sprintf(hx, "%02X", id.id[i]);
strcat(_idString, hx);
}
tusb_init();
irq_set_exclusive_handler(PICO_STDIO_USB_LOW_PRIORITY_IRQ, low_priority_worker_irq);
irq_set_enabled(PICO_STDIO_USB_LOW_PRIORITY_IRQ, true);
mutex_init(&usb_mutex);
add_alarm_in_us(PICO_STDIO_USB_TASK_INTERVAL_US, timer_task, NULL, true);
_running = true;
}
@@ -188,7 +62,7 @@ void SerialUSB::end() {
}
int SerialUSB::peek() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -198,7 +72,7 @@ int SerialUSB::peek() {
}
int SerialUSB::read() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return -1;
}
@@ -210,7 +84,7 @@ int SerialUSB::read() {
}
int SerialUSB::available() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -219,7 +93,7 @@ int SerialUSB::available() {
}
int SerialUSB::availableForWrite() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -228,7 +102,7 @@ int SerialUSB::availableForWrite() {
}
void SerialUSB::flush() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return;
}
@@ -241,7 +115,7 @@ size_t SerialUSB::write(uint8_t c) {
}
size_t SerialUSB::write(const uint8_t *buf, size_t length) {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -276,7 +150,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
}
SerialUSB::operator bool() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return false;
}
+2 -1
View File
@@ -19,6 +19,7 @@
*/
#include <Arduino.h>
#include "RP2040USB.h"
#include <pico/stdlib.h>
#include <pico/multicore.h>
@@ -59,6 +60,7 @@ extern "C" int main() {
mutex_init(&_pioMutex);
initVariant();
__USBStart();
#ifndef DISABLE_USB_SERIAL
// Enable serial port for reset/upload always
@@ -102,7 +104,6 @@ extern "C" int main() {
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#include <bits/stdc++.h>
#undef errno
+1
View File
@@ -31,6 +31,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
SPI <spi>
Wire(I2C) <wire>
File Systems (SD, SDFS, LittleFS) <fs>
USB Keyboard/Mouse <usb>
Multicore Processing <multicore>
Ported/Optimized Libraries <libraries>
+24
View File
@@ -80,6 +80,30 @@ the ``USB Serial (CDC)`` driver.
.. image:: images/install_driver_old_win.png
Windows 7 Installation Problems
-------------------------------
When running MalwareBytes antivirus (or others) the scanner may lock the compiler or other toolchain executables, causing installation or build failures. (Thanks to @Andy2No)
Symptoms include:
*Access denied during update in the boards manager - affects the .exe files, because MalwareBytes has locked them.
* Access denied during compilation, to one of the .exe files - same reason.
* Can't delete the .exe files - they're locked by MalwareBytes.
A workaround is possible, involving setting the toolchain as an "excluded directory" and reinstalling.
1. In MalwareBytes Settings, click the Exclusions tab. Add an exclusion for the equivalent of this folder path:
``C:\Users{YOUR_USERNAME_HERE}\AppData\Local\Arduino15\packages\rp2040\tools\pqt-gcc\1.1.0-a-81a1771``
2. Reboot to unlock the files.
3. Do the boards manager installation / upgrade again.
4. Set the board type, e.g. to Raspberry Pi Pico and check it can compile.
Uploading Filesystem Images
---------------------------
The onboard flash filesystem for the Pico, LittleFS, lets you upload a filesystem image from the sketch directory for your sketch to use. Download the needed plugin from
+11
View File
@@ -0,0 +1,11 @@
USB Keyboard and Mouse
======================
The Arduino-Pico core includes ported versions of the standard Arduino
``Keyboard`` and ``Mouse`` libraries. These libraries allow you to
emulate a keyboard or mouse with the Pico in your sketches.
See the examples and Arduino Reference at
https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
and
https://www.arduino.cc/reference/en/language/functions/usb/mouse
BIN
View File
Binary file not shown.
Submodule libraries/Keyboard added at e8c1394e69
+1
Submodule libraries/Mouse added at 1b39fd21e5
+1 -1
View File
@@ -106,7 +106,7 @@ recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compil
## Combine gc-sections, archives, and objects
recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3" "{runtime.platform.path}/tools/simplesub.py" --input "{runtime.platform.path}/lib/memmap_default.ld" --out "{build.path}/memmap_default.ld" --sub __FLASH_LENGTH__ {build.flash_length} --sub __EEPROM_START__ {build.eeprom_start} --sub __FS_START__ {build.fs_start} --sub __FS_END__ {build.fs_end}
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nosys.specs -Wl,--start-group {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "{runtime.platform.path}/lib/libpico.a" -lm "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" "{runtime.platform.path}/assembly/{build.boot2}.S" -lc -lstdc++ -Wl,--end-group
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nosys.specs -Wl,--as-needed -Wl,--start-group {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" -Wl,--whole-archive "{runtime.platform.path}/lib/libpico.a" -Wl,--no-whole-archive -lm "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" "{runtime.platform.path}/assembly/{build.boot2}.S" -lc -lstdc++ -Wl,--end-group
## Create output (UF2 file)
recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2"
+3 -1
View File
@@ -23,6 +23,8 @@ target_compile_options(pico PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
)
include_directories(BEFORE ${PICO_SDK_PATH}/../tools/libpico)
target_link_libraries(pico
boot_stage2
hardware_adc
@@ -63,10 +65,10 @@ target_link_libraries(pico
pico_platform
pico_runtime
pico_standard_link
pico_stdio_usb
pico_stdlib
pico_unique_id
tinyusb
tinyusb_device_unmarked
pico_audio
pico_audio_i2s
)
+116
View File
@@ -0,0 +1,116 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
// defined by board.mk
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
// RHPort number used for device can be defined by board.mk, default to port 0
#ifndef BOARD_DEVICE_RHPORT_NUM
#define BOARD_DEVICE_RHPORT_NUM 0
#endif
// RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56)
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
#else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
#endif
#endif
// Device mode with rhport and speed defined by board.mk
#if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#else
#error "Incorrect RHPort configuration"
#endif
// This example doesn't use an RTOS
//#define CFG_TUSB_OS OPT_OS_NONE
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//------------- CLASS -------------//
#define CFG_TUD_HID (2)
#define CFG_TUD_CDC (1)
#define CFG_TUD_MSC (0)
#define CFG_TUD_MIDI (1)
#define CFG_TUD_VENDOR (0)
#define CFG_TUD_CDC_RX_BUFSIZE (256)
#define CFG_TUD_CDC_TX_BUFSIZE (256)
#define CFG_TUD_MIDI_RX_BUFSIZE (64)
#define CFG_TUD_MIDI_TX_BUFSIZE (64)
// HID buffer size Should be sufficient to hold ID (if any) + Data
#define CFG_TUD_HID_EP_BUFSIZE (64)
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */
+4 -4
View File
@@ -44,7 +44,7 @@ static const uint8_t A1 = (27u);
static const uint8_t A2 = (28u);
static const uint8_t A3 = (29u);
static const uint8_t SS = PIN_SPI1_SS;
static const uint8_t MOSI = PIN_SPI1_MOSI;
static const uint8_t MISO = PIN_SPI1_MISO;
static const uint8_t SCK = PIN_SPI1_SCK;
static const uint8_t SS = PIN_SPI0_SS;
static const uint8_t MOSI = PIN_SPI0_MOSI;
static const uint8_t MISO = PIN_SPI0_MISO;
static const uint8_t SCK = PIN_SPI0_SCK;