Skip to content

Commit 0f447c8

Browse files
author
Taylor.An
committed
Merge commit '4cc8e6d6db7533346a81c59657c5d76cf246668b' into 20230519-2
2 parents 31cc288 + 4cc8e6d commit 0f447c8

32 files changed

+1064
-36
lines changed

cores/rp2040/FS.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,12 @@ File File::openNextFile() {
192192
String File::readString() {
193193
String ret;
194194
ret.reserve(size() - position());
195-
char temp[256 + 1];
196-
int countRead = readBytes(temp, sizeof(temp) - 1);
197-
while (countRead > 0) {
198-
temp[countRead] = 0;
199-
ret += temp;
200-
countRead = readBytes(temp, sizeof(temp) - 1);
201-
}
195+
uint8_t temp[256];
196+
int countRead;
197+
do {
198+
countRead = read(temp, sizeof(temp));
199+
ret.concat(temp, countRead);
200+
} while (countRead > 0);
202201
return ret;
203202
}
204203

cores/rp2040/RP2040USB.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ static int __usb_task_irq;
6868
#define USBD_STR_SERIAL (0x03)
6969
#define USBD_STR_CDC (0x04)
7070

71-
7271
#define EPNUM_HID 0x83
7372

73+
#define USBD_MSC_EPOUT 0x03
74+
#define USBD_MSC_EPIN 0x84
75+
#define USBD_MSC_EPSIZE 64
7476

7577
const uint8_t *tud_descriptor_device_cb(void) {
7678
static tusb_desc_device_t usbd_desc_device = {
@@ -89,7 +91,7 @@ const uint8_t *tud_descriptor_device_cb(void) {
8991
.iSerialNumber = USBD_STR_SERIAL,
9092
.bNumConfigurations = 1
9193
};
92-
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick) {
94+
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick && !__USBInstallMassStorage) {
9395
// Can use as-is, this is the default USB case
9496
return (const uint8_t *)&usbd_desc_device;
9597
}
@@ -103,6 +105,9 @@ const uint8_t *tud_descriptor_device_cb(void) {
103105
if (__USBInstallJoystick) {
104106
usbd_desc_device.idProduct |= 0x0100;
105107
}
108+
if (__USBInstallMassStorage) {
109+
usbd_desc_device.idProduct ^= 0x2000;
110+
}
106111
// Set the device class to 0 to indicate multiple device classes
107112
usbd_desc_device.bDeviceClass = 0;
108113
usbd_desc_device.bDeviceSubClass = 0;
@@ -223,7 +228,7 @@ void __SetupUSBDescriptor() {
223228
if (!usbd_desc_cfg) {
224229
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallJoystick;
225230

226-
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0);
231+
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMassStorage ? 1 : 0);
227232

228233
uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
229234
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
@@ -238,7 +243,12 @@ void __SetupUSBDescriptor() {
238243
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
239244
};
240245

241-
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0);
246+
uint8_t msd_itf = interface_count - 1;
247+
uint8_t msd_desc[TUD_MSC_DESC_LEN] = {
248+
TUD_MSC_DESCRIPTOR(msd_itf, 0, USBD_MSC_EPOUT, USBD_MSC_EPIN, USBD_MSC_EPSIZE)
249+
};
250+
251+
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMassStorage ? sizeof(msd_desc) : 0);
242252

243253
uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
244254
// Config number, interface count, string index, total length, attribute, power in mA
@@ -260,6 +270,10 @@ void __SetupUSBDescriptor() {
260270
memcpy(ptr, hid_desc, sizeof(hid_desc));
261271
ptr += sizeof(hid_desc);
262272
}
273+
if (__USBInstallMassStorage) {
274+
memcpy(ptr, msd_desc, sizeof(msd_desc));
275+
ptr += sizeof(msd_desc);
276+
}
263277
}
264278
}
265279
}
@@ -367,4 +381,55 @@ extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_r
367381
(void) bufsize;
368382
}
369383

384+
extern "C" int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) __attribute__((weak));
385+
extern "C" int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
386+
(void) lun;
387+
(void) lba;
388+
(void) offset;
389+
(void) buffer;
390+
(void) bufsize;
391+
return -1;
392+
}
393+
394+
extern "C" bool tud_msc_test_unit_ready_cb(uint8_t lun) __attribute__((weak));
395+
extern "C" bool tud_msc_test_unit_ready_cb(uint8_t lun) {
396+
(void) lun;
397+
return false;
398+
}
399+
400+
extern "C" int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) __attribute__((weak));
401+
extern "C" int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
402+
(void) lun;
403+
(void) lba;
404+
(void) offset;
405+
(void) buffer;
406+
(void) bufsize;
407+
return -1;
408+
}
409+
410+
extern "C" int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) __attribute__((weak));
411+
extern "C" int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) {
412+
(void) lun;
413+
(void) scsi_cmd;
414+
(void) buffer;
415+
(void) bufsize;
416+
return 0;
417+
}
418+
419+
extern "C" void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) __attribute__((weak));
420+
extern "C" void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
421+
(void) lun;
422+
*block_count = 0;
423+
*block_size = 0;
424+
}
425+
426+
extern "C" void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) __attribute__((weak));
427+
extern "C" void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
428+
(void) lun;
429+
vendor_id[0] = 0;
430+
product_id[0] = 0;
431+
product_rev[0] = 0;
432+
}
433+
434+
370435
#endif

cores/rp2040/RP2040USB.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern void __USBInstallSerial() __attribute__((weak));
2626
extern void __USBInstallKeyboard() __attribute__((weak));
2727
extern void __USBInstallJoystick() __attribute__((weak));
2828
extern void __USBInstallMouse() __attribute__((weak));
29+
extern void __USBInstallMassStorage() __attribute__((weak));
2930

3031
// Big, global USB mutex, shared with all USB devices to make sure we don't
3132
// have multiple cores updating the TUSB state in parallel

cores/rp2040/RP2040Version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
22
#define ARDUINO_PICO_MAJOR 2
33
#define ARDUINO_PICO_MINOR 6
4-
#define ARDUINO_PICO_REVISION 4
5-
#define ARDUINO_PICO_VERSION_STR "2.6.4"
4+
#define ARDUINO_PICO_REVISION 5
5+
#define ARDUINO_PICO_VERSION_STR "2.6.5"

cores/rp2040/SerialUART.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,12 @@ void __not_in_flash_func(SerialUART::_handleIRQ)(bool inIRQ) {
390390
// ICR is write-to-clear
391391
uart_get_hw(_uart)->icr = UART_UARTICR_RTIC_BITS | UART_UARTICR_RXIC_BITS;
392392
while (uart_is_readable(_uart)) {
393-
auto val = uart_getc(_uart);
393+
uint32_t raw = uart_get_hw(_uart)->dr;
394+
if (raw & 0x700) {
395+
// Framing, Parity, or Break. Ignore this bad char
396+
continue;
397+
}
398+
uint8_t val = raw & 0xff;
394399
auto next_writer = _writer + 1;
395400
if (next_writer == _fifoSize) {
396401
next_writer = 0;

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@
5454
# built documents.
5555
#
5656
# The short X.Y version.
57-
version = u'2.6.4'
57+
version = u'2.6.5'
5858
# The full version, including alpha/beta/rc tags.
59-
release = u'2.6.4'
59+
release = u'2.6.5'
6060

6161
# The language for content autogenerated by Sphinx. Refer to documentation
6262
# for a list of supported languages.

docs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
3939
USB (Arduino and Adafruit_TinyUSB) <usb>
4040
Multicore Processing <multicore>
4141

42+
Single File USB Drive <singlefile>
43+
4244
FreeRTOS SMP (multicore) <freertos>
4345

4446
WiFi (Pico-W Support) <wifi>

docs/singlefile.rst

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
SingleFileDrive
2+
===============
3+
4+
USB drive mode is supported through the ``SingleFileDrive`` class which
5+
allows the Pico to emulate a FAT-formatted USB stick while preserving the
6+
onboard LittleFS filesystem. A single file can be exported this way without
7+
needing to use FAT as the onboard filesystem (FAT is not appropriate for
8+
flash-based devices without complicated wear leveling because of the update
9+
frequency of the FAT tables).
10+
11+
This emulation is very simple and only allows for the reading of the single
12+
file, and deleting it.
13+
14+
Callbacks, Interrupt Safety, and File Operations
15+
------------------------------------------------
16+
17+
The ``SingleFileDrive`` library allows your application to get a callback
18+
when a PC attempts to mount or unmount the Pico as a drive. Your app can
19+
also get a callback if the user attempts to delete the file (but your
20+
sketch does not actually need to delete the file, it's up to you).
21+
22+
Note that when the USB drive is mounted by a PC it is not safe for your
23+
main sketch to make changes to the LittleFS filesystem or the file being
24+
exported. So, normally, your ``onPlug`` callback will set a flag letting
25+
your application know not to touch the filesystem, with the ``onUnplug``
26+
callback clearing this flag.
27+
28+
Also, because the USB port can be connected at any time, it is important
29+
to disable interrupts using ``noInterrupts()`` before writing to a file
30+
you will be exporting (and restoring them with ``interrupts()`` afterwards).
31+
It is also important to ``close()`` the file after each update, or the
32+
on-flash version the ``SingleFileDrive`` will attempt to export may not be
33+
up to date causing issues later on.
34+
35+
See the included ``DataLoggerUSB`` sketch for an example of working with
36+
these limitations.
37+
38+
Using SingleFileDrive
39+
---------------------
40+
41+
Implementing the drive requires including the header file, starting LittleFS,
42+
defining your callbacks, and telling the library what file to export. No
43+
polling or other calls are required outside of your ``setup()``. (Note that
44+
the callback routines allow for a parameter to be passed to them, but in most
45+
cases this can be safely ignored.)
46+
47+
.. code:: cpp
48+
49+
#include <LittleFS.h>
50+
#include <SingleFileDrive.h>
51+
52+
void myPlugCB(uint32_t data) {
53+
// Tell my app not to write to flash, we're connected
54+
}
55+
56+
void myUnplugCB(uint32_t data) {
57+
// I can start writing to flash again
58+
}
59+
60+
void myDeleteDB(uint32_t data) {
61+
// Maybe LittleFS.remove("myfile.txt")? or do nothing
62+
}
63+
64+
void setup() {
65+
LittleFS.begin();
66+
singleFileDrive.onPlug(myPlugCB);
67+
singleFileDrive.onUnplug(myUnplugCB);
68+
singleFileDrive.onDelete(myDeleteCB);
69+
singleFileDrive.begin("littlefsfile.csv", "Data Recorder.csv");
70+
// ... rest of setup ...
71+
}
72+
73+
void loop() {
74+
// Take some measurements, delay, etc.
75+
if (okay-to-write) {
76+
noInterrupts();
77+
File f = LittleFS.open("littlefsfile.csv", "a");
78+
f.printf("%d,%d,%d\n", data1, data2, data3);
79+
f.close();
80+
interrupts();
81+
}
82+
}

include/tusb_config.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,14 @@
7272
//------------- CLASS -------------//
7373
#define CFG_TUD_HID (2)
7474
#define CFG_TUD_CDC (1)
75-
#define CFG_TUD_MSC (0)
75+
#define CFG_TUD_MSC (1)
7676
#define CFG_TUD_MIDI (0)
7777
#define CFG_TUD_VENDOR (0)
7878

7979
#define CFG_TUD_CDC_RX_BUFSIZE (256)
8080
#define CFG_TUD_CDC_TX_BUFSIZE (256)
8181

82-
#define CFG_TUD_MIDI_RX_BUFSIZE (64)
83-
#define CFG_TUD_MIDI_TX_BUFSIZE (64)
82+
#define CFG_TUD_MSC_EP_BUFSIZE (64)
8483

8584
// HID buffer size Should be sufficient to hold ID (if any) + Data
8685
#define CFG_TUD_HID_EP_BUFSIZE (64)

lib/libpico-ipv6.a

49 KB
Binary file not shown.

lib/libpico.a

49 KB
Binary file not shown.

libraries/I2S/src/AudioRingBuffer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ int AudioRingBuffer::available() {
215215
}
216216
int avail;
217217
avail = _wordsPerBuffer - _userOff;
218-
avail += ((_bufferCount + _curBuffer - _userBuffer) % _bufferCount) * _wordsPerBuffer;
218+
avail += ((_bufferCount + _curBuffer - _userBuffer) % _bufferCount) * _wordsPerBuffer /* total other buffers */ - _wordsPerBuffer /* minus the one currently being output */;
219+
if (avail < 0) {
220+
avail = 0; // Should never hit
221+
}
219222
return avail;
220223
}
221224

libraries/PicoOTA/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ maintainer=Earle F. Philhower, III <[email protected]>
55
sentence=Configures requests for OTA bootloader
66
paragraph=Example repository for Ethernet drivers
77
category=Device Control
8-
url=https://github.com/earlephilhower.arduino-pico
8+
url=https://github.com/earlephilhower/arduino-pico
99
architectures=rp2040
1010
dot_a_linkage=true

0 commit comments

Comments
 (0)