USB Serial Device Stack for Raspberry Pico / Pico-W 1
This (beta version) repository is intended for anyone :-
- With a general interest in USB CDC/ACM Serial Ports on a Pico device
- Looking for additional USB functionality - suspend / resume / wakeup remote (sleeping) host
- Looking for additional serial port functionality - e.g. port signalling DSR/DCD/Ring to host
- Looking for an alternative USB Serial Stack device driver for Pico / Pico-W / Other RP2040 boards
What's New
16th October 2024
- functional testing with lurk101/pshell fork
- fix issues identified by above
- re-arrange endpoints
17th October 2024
- Fix EP1 handler defect
- Add
__not_in_flash_functo various functions - Multicore testing USB IRQ5 offload to core1
27th October 2024
- Consolidate buffer functions
- Add USB suspend / resume 2
- Add USB wakeup host from Pico
More Information
Design Pattern
- Written in C, using Raspberry SDK version 2.0.0
- Bespoke development for Pico and compatible boards only
- All interrupt-driven, no background tasks or timers required
- Uses SDK's queues and stdio_driver for stdio integration
- Library deployment using supplied
CMakeLists.txtfile - SDK's stdio library
pico_stdio_usbnot required - Modular design to support future developments
Installing
Non-Debug version
- Copy directory
lib_usb_cdc_serialto your project directory - Add
#include "lib_usb_cdc_serial/API_usb_serial.h"to start of your project'smain.cfile - Add
set(SKIP_PICO_STDIO_USB 1)to your project'sCMakeLists.txtfile, beforepico_sdk_init() - Add
add_subdirectory(lib_usb_cdc_serial)to your project'sCMakeLists.txtfile - Add
lib_usb_cdc_serialto thetarget_link_libraries()section of your project'sCMakeLists.txt - Set
pico_enable_stdio_usb(your_project_name 0)in your project'sCMakeLists.txtfile - Set
(PICO_SDK_VERSION_STRING VERSION_LESS "2.0.0")in your project'sCMakeLists.txtfile - Add
usb_start_serial(true, true, true);to theint main()section of your project'smain.cfile - Stub function
void usb_error(uint8_t error_level)can be used drive error LEDs via GPIO etc. 3 - See USB Serial Port Functions for functions to add to your program
Debug version
-
Copy directory
lib_usb_cdc_serial_debugto your project directory -
Add
#include "lib_usb_cdc_serial_debug/API_usb_serial.h"to start of your project'smain.cfile -
Add
#include "lib_usb_cdc_serial_debug/include/USB_uart_printf.h"to start of your project'smain.cfile -
Add
set(SKIP_PICO_STDIO_USB 1)to your project'sCMakeLists.txtfile, beforepico_sdk_init() -
Add
add_subdirectory(lib_usb_cdc_serial_debug)to your project'sCMakeLists.txtfile -
Add
lib_usb_cdc_serialto thetarget_link_libraries()section of your project'sCMakeLists.txt -
Add
pico_multicoreto thetarget_link_libraries()section of your project'sCMakeLists.txt -
Set
pico_enable_stdio_usb(your_project_name 0)in your project'sCMakeLists.txtfile -
Set
pico_enable_stdio_uart(your_project_name 0)in your project'sCMakeLists.txtfile -
Set
pico_enable_stdio_usb(your_project_name 0)in your project'sCMakeLists.txtfile -
Set
(PICO_SDK_VERSION_STRING VERSION_LESS "2.0.0")in your project'sCMakeLists.txtfile -
Add
initialise_uart_printf();to theint main()section of your project'smain.cfile -
Add
usb_start_serial(true, true);to theint main()section of your project'smain.cfile -
Stub function
void usb_error(uint8_t error_level)can be used drive error LEDs via GPIO etc. 3 -
See USB Serial Port Functions for functions to add to your program
Multicore
USB Interrupt IRQ5 can be offloaded to core1 by
- adding
#include "pico/multicore.h"to main.c - adding
multicore_launch_core1(core1_entry)to main.c; - moving
usb_start_serial(true, true, true);frommain()tocore1_entry() - adding
pico_multicoreto thetarget_link_libraries()section of your project'sCMakeLists.txt
void core1_entry() {
usb_start_serial(true, true, true);
busy_wait_ms(1);
while (true) {
tight_loop_contents();
};
}
Currently in testing with pshell
Issues
- USB IRQ5 needs elevated priority for stdin
(getc, scanf etc. )only - - Elevated IRQ5 priority may not be correct or fully SDK-compliant
Testing
Works with original Pico, Pico W and other RP2040 boards
CoolTerm is recommended for signalling testing DSR/DCD/Ring
PuTTY is recommended for general debug
USB Enumeration
Pico appears to enumerate correctly with :-
-
Windows host and create a new COM port
-
Mac host and create a new
/dev/tty.usbmodem...device
Pico stdio
Pico stdio and SDK functions all appear to work as expected, including :-
printf();scanf();putc();and variants;getc();and variants
Test exclusions
- Not tested with RP2350 Pico 2
- Not tested for co-existance with other USB stacks4
- Not tested with RTOS or heavily-loaded multicore operation
To Do
- Pico 2 testing
- Port Flow Control
- Port signalling handshake
- Error handling improvements
- GPIO LEDS for port signals DSR,DTR,RING etc.
- Other Raspberry & Linux host testing.
- Multiple Com port support
Function List
SDK function stdio_set_driver_enabled(); can be used normally if required
Pico can also be rebooted with a Break command from PuTTY or other client
PuTTY > Special Command > Break
Acknowledgements
Glossary
| Description | |
|---|---|
| CDC | Communications Device Class (of USB) |
| ACM | Abstract Control Model (subclass of CDC) |
| DSR | Data Set Ready |
| DCD | Data Carrier Detect |
Demo Versions
Check that a COM port is created in Device manager
Use PuTTY or similar client to connect to it.
Check that a /dev/tty.usbmodem... is created
Use cu or similar client to connect to it.
e.g. sudo cu -l /dev/tty/usbmodem1234
Shows Enumeration and IRQ activity on Pico uart0 (via debug probe or similar)
Simple menu allows for CDC notification testing - Ring, DCD, DSR
Simple menu similar to above
Other tests can be enabled in stdio_tests.c
No debug output. Stubs can be developed to drive LEDs etc if required.