Rpi Pico Usb device mode


Eduard2

Honourable Member

Goede morgen,

Het forum heeft zijn doel bereikt. Met deze informatie kan ik weer aan de slag. Het zit er dik in dat de snelheid hoog genoeg is om een 16bit audiosignaal met 44,1 kHz samplerate over de usb te sturen.

Als volgende proef ga ik de rollen omdraaien. De pc gaat data op de usb sturen en de pico zal die op aansluitpinnen brengen. Met de oscilloscoop kan dan worden bekeken welke snelheid haalbaar is.

Ik verwacht dat Hensz gelijk heeft. Daarom begin ik nu met grotere rijen getallen. Als de snelheid nog wat hoger kan dan de huidige meting dan heb ik ruim marge. Het is dan niet nodig TinyUsb te gebruiken.

Usb blijft voor mij een moeilijk ding. Als pc eindgebruiker is het meestal plug and play. Op een microcontroller heb je geen OS dat de bitjes netjes op een rij zet. Meestal is het zoeken naar software die iemand anders daarvoor heeft geschreven. Daar geldt de uitspraak: "een goed geschreven code begrijpen is vaak moeilijker dan een slecht programma schrijven".

Vriendelijke groeten,

Eduard

16-bit audio is effectief 44100 x 4 = 176400 bytes (ongeveer 1 Mbit) per second. Geen enkel probleem voor USB 1.1

USB is inderdaad nogal complex. Dat geldt voor iedereen die er in duikt. Voor Audio moet je een class Audio device bouwen in de PICO zodat de PC ziet dat hij audio data kan sturen.

USB heeft daar een standaard voor. Zie https://www.usb.org/sites/default/files/audio10.pdf

Hensz

Golden Member

Op 8 juni 2021 13:51:52 schreef deKees:
16-bit audio is effectief 44100 x 4 = 176400 bytes (ongeveer 1 Mbit) per second. Geen enkel probleem voor USB 1.1

Dat zou ik niet willen zeggen. CD branders met USB 1.1 hadden destijds grote moeite om voldoende data naar de brander te sturen om het e.e.a. succes te laten hebben. Je computer tegelijkertijd ook nog iets anders laten doen was garantie voor een falende burn.

Don't Panic!

Da's vaak het probleem ook.
Oversturen van de data is zinloos als de processor niet genoeg 'vrije tijd' heeft om er iets zinnigs mee te doen en te verwerken.

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Dat verhaal dateert uit de tijd dat er min of meer synchroon naar de CD geschreven moest worden. En al heel snel was schrijven op "1x" snelheid achterhaald en kon dat ook 2x, 4x of 8x. En DAN zit je ineens voorbij wat USB KAN, dus op USB zou het best kunnen dat je 4x kon schrijven, maar dat je dan wel "alles goed" moet doen om geen buffer underruns in de writer te krijgen.

USB heeft speciale voorzieningen voor situaties waarbij een afgesproken hoeveelheid data per seconde getransporteert moet worden. Dus juist "CD branden" is iets wat goed zou moeten gaan. Of op z'n minst niet falen DOOR USB.

[Bericht gewijzigd door rew op 8 juni 2021 19:28:39 (23%)]

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Beste forumleden,

Via ttyACM0 is de snelheid te klein om met audio aan de slag te gaan.

int main() {
char eenstr[100], nulstr[100];
for(int i=0; i<99; i++){eenstr = '1'; nulstr = '0';};

FILE *fp;
fp = fopen("/dev/ttyACM0", "w");

for(int j=0; j<10000; j++) {
fputs(nulstr,fp);
fputs(eenstr,fp);
} // end for

fclose(fp);
return(0);
}

Deze test vraagt 58 seconden om vanaf de pc tienduizend keer 200 charakters naar de pico te schrijven. Als ik deze keer geen telfout maak dan komt dat neer op ongeveer 35000 bytes per seconde. Dat is te weinig voor audio. Ik ga nogeens uitpluizen of het met heel grote buffers sneller kan. Vermoedelijk zal er niets anders opzitten dan TinyUsb te leren gebruiken.

Vriendelijke groeten,

Eduard

Hi speed data transfers zijn wat lastiger met USB. Hier staat e.e.a. beschreven: https://www.beyondlogic.org/usbnutshell/usb1.shtml

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

USB werkt met pakketten data. Max 1 pakket per milliseconde. De max data hangt af van het soort transfer. Een TTY werkt met interrupt transfers, die op USB1.1 full speed (12Mbit) een max payload hebben van 64 byte. Met 1 Packet per milliseconde zit je dan vast aan 64Kb max per seconde.

Audio werkt met isochrone transfers, omdat timing belangrijk is. Dan heb je max 1023 bytes per pakket, en vervalt error correctie. En dus ook max 1 Mbyte per seconde data transfer.

En dat gaat niet over een TTY verbinding. Daarvoor moet je in de PICO een audio driver implementeren op je USB engine, en ook op de PC een audio kanaal openen.

.

[Bericht gewijzigd door deKees op 9 juni 2021 11:53:02 (100%)]

Op 9 juni 2021 11:52:03 schreef deKees:
USB werkt met pakketten data. Max 1 pakket per milliseconde. De max data hangt af van het soort transfer. Een TTY werkt met interrupt transfers, die op USB1.1 full speed (12Mbit) een max payload hebben van 64 byte. Met 1 Packet per milliseconde zit je dan vast aan 64Kb max per seconde.

Dat klopt kennelijk niet, want ik haal 153kb/sec.

code:


getafix:~> time cat test123.dat > /dev/ttyACM1 
0.012u 0.000s 0:07.15 0.1%      0+0k 0+0io 0pf+0w
getafix:~> wc test123.dat
  10000   20000 1100000 test123.dat
getafix:~> bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1100000/07.15
153846.15384615384615384615

Dit is met een STM32F072 als target, dus het zegt niet dat het met een PICO zo hard kan, maar ik verwacht van wel. De pico CPU is 1 tikje moderner (M0+ ipv M0) en bijna 3x sneller (133 ipv 48MHz).

Eduard,

Je gebruikt nogal slechte methodes om throguhput te testen. Het zou best kunnen dat je systeem vindt dat een fputs naar het device "serial port" direct verstuurd moet worden, dus dat ie regelt dat er direct een "100 byte string" verstuurd wordt. Dat zou dan een 64+36 byte pakket worden, waarbij de rest van het 36-byte-pakket ineens geen mogelijkheid meer voor is om dat te benutten.

Daarnaast je testprogramma bevat een essentiele fout.

Ik snap niet dat je compiler er mee accoord gaat, maar je bedoel waarschijnlijk:

eenstr = '1';

waar nu

eenstr = '1';

staat. Daarnaast moeten die strings afgesloten worden. Op zijn minst:

eenstr[99] = '\0';

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Dag Rew,

De gcc compiler gaf geen foutmelding. Een string moet met eindnul worden afgesloten. Achteraf heb ik dat aangepast en ook de stringlengte tot 1000 charakters verhoogd. Dat werkt en geeft nauwelijks een verschil in snelheid.

Ik twijfel of de pico op dat punt sneller is dan uw STM32F072. De pico heeft twee PLL's. De ene levert de systeemklok die standaard 125 MHz bedraagt. (max van de chip is 133 MHz). De tweede PLL levert 48 MHz voor de USB.

Met uw testmethode lijkt de pico wel een slak met opgetrokken handrem. 31500 char/sec is het beste resultaat. Mijn testfile heeft 20000 lijnen met 64 char. Alle char, uitgezonderd het regeleind, zijn '1'. De beste timing is iets meer dan 38 seconden.

Vriendelijke groeten,

Eduard

[Bericht gewijzigd door Eduard2 op 9 juni 2021 17:20:06 (23%)]

Ik heb even:
* Pico SDK geinstalleerd.
* een test programma geschreven.
* gemeten.

Mijn pico haalt 450 kbyte per seconden over CDC. De jouwe is kapot.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Hensz

Golden Member

Lijkt me leuk om jou testprogramma eens door Eduard te laten runnen. Zijn testje is niet erg efficiënt, dus als jullie met hetzelfde programmaatje dezelfde doorvoer krijgen, dan weten we dat ie toch niet kapot is en idd ruimschoots snel genoeg gaat voor wat Eduard er mee van plan is. :)

Don't Panic!
Eduard2

Honourable Member

Dag Rew,

Is uw testprogramma beschikbaar ? Graag had ik dezelfde proef genomen. Als mijn pico defect zou zijn dan zal dat vlug aan het licht komen. Ik heb er nog een paar. Het lijkt me vreemd dat de pico door een elektrisch defect te langzaam zou worden. Een foute instelling of niet de juiste software versie lijkt me waarschijnlijker. Mogelijk deugt het programma dat ik op de pico installeerde niet.

Intussen probeerde ik verdere foutoorzaken uit te sluiten. Teneinde de pc uit te sluiten herhaalde ik de test op een laptop met Lubuntu. Zelfde resultaat. Doe ik mogelijk iets fout met het gebruik van de usb ? Moet de pico worden gemount ? Dat heb ik niet gedaan.

Vriendelijke groeten,

Eduard

[Bericht gewijzigd door Eduard2 op 10 juni 2021 09:17:14 (23%)]

c code:

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"

char buf[1028];

int main() 
{
  int i;

    stdio_init_all();
    memset (buf, '.', 1024);
    buf[1022] = '\r';
    buf[1023] = '\n';
    buf[1024] = 0;
    for (i=69;i<1024;i+=70)
       buf[i] = '\n';

    for (i=0;i<10;i++) {
        printf("Hello, world! %d\n", i);
        sleep_ms(1000);
    }
    for (i=0;i<10240;i++) {
        sprintf (buf, "block %d.......\r\n", i);
        memset (buf+12, '.', 12);
        printf ("%s", buf);
    }

    return 0;
}

1Mbyte was te snel voor mij om met de hand te meten. Dus 10Mbyte doet er ongeveer 22 sec over op mijn computer/pico.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Bedankt rew,

Je zou het niet geloven maar het is waar. Uw usb is een haas en de mijne blijft een slak. Aan de pc kant testte ik zowel met: time cat /dev/ttyACM0 als met Serial portterminal. Om de test redelijk kort te houden verkleinde ik naar 1 MByte. 1 MByte vraagt ongeveer 100 seconden.

Intussen heb ik de proef hernomen. Een tweede pico geeft hetzelfde resultaat. Een andere pc idem. We kunnen dus een defect aan pc of pico uitsluiten.
Alle componenten behalve de ontwikkelingsomgeving zijn intussen veranderd en toch blijft usb hier ondermaats presteren.

Hoe compileer je ? Ik gebruik geen Visual studio maar de commandline. Bij de installatie op de pc heb de Getting Started gevolgd. Ik overweeg alle bestanden te verwijderen en opnieuw te installeren.

Vriendelijke groeten,

Eduard

Zijn de USB descriptors ook goed ingevuld? (anders krijg je ook problemen)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Arco, met bovenstaand programma heb je "alles", de rest zit in de library die in de SDK zit.

Je zou het niet geloven maar ....

Klopt. Ik geloof het niet.

Je test verkeerd. Misschien ligt het aan je host computer, maar in ieder geval niet aan de pico.

Hoe compileer je ? Ik gebruik geen Visual studio maar de commandline.

Right. Ik ook

Bij de installatie op de pc heb de Getting Started gevolgd.

Ik ook

Ik overweeg alle bestanden te verwijderen en opnieuw te installeren.

Dat is een windows-oplossing: retry, reboot, reinstall. Ik doe daar niet aan mee.

Edit: Dat je compiler stuk is en werkende-maar-langzaam code genereert gaat er bij mij ook niet in. Bijgevoegd m'n binary.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Dag rew,

Eerst het goede nieuws. De pc en de pico zijn niet defect. Uw binary is 30 keer sneller dan mijn code. In minder dan 33 seconden werd 10 MByte verzonden. Dat is meer dan schitterend.

Intussen heb ik alle oude bestanden van de pc verwijderd en opnieuw geïnstalleerd. Mijn nieuwste binary blijft even traag. Behalve de CMakeLists.txt file hebben we nu ongeveer alles uitgesloten. De kans is groot dat de fout daar zit. Dit is de verdachte file:

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(test_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(test2
test2.c
)

pico_enable_stdio_usb(test2 1)
pico_add_extra_outputs(test2)
target_link_libraries(test2 pico_stdlib)
------------------------------------------

Ik begrijp lang niet alle details van deze file. De file werd aangemaakt naar analogie met de aangeleverde voorbeelden.

Hartelijk dank voor uw hulp.

Vriendelijke groeten,

Eduard

In de hello_world/usb directory vind ik CMakeLists.txt:

code:

if (TARGET tinyusb_device)
    add_executable(hello_usb
            hello_usb.c
            )

    # Pull in our pico_stdlib which aggregates commonly used features
    target_link_libraries(hello_usb pico_stdlib)

    # enable usb output, disable uart output
    pico_enable_stdio_usb(hello_usb 1)
    pico_enable_stdio_uart(hello_usb 0)

    # create map/bin/hex/uf2 file etc.
    pico_add_extra_outputs(hello_usb)

    # add url via pico_set_program_url
    example_auto_set_url(hello_usb)
elseif(PICO_ON_DEVICE)
    message(WARNING "not building hello_usb because TinyUSB submodule is not initialized in the SDK")
endif()

De directory daarboven vind ik:

code:

add_subdirectory(serial)
add_subdirectory(usb)

en daarboven:

code:


cmake_minimum_required(VERSION 3.12)

# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)

project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})

# Initialize the SDK
pico_sdk_init()

include(example_auto_set_url.cmake)
# Add blink example
add_subdirectory(blink)

# Add hello world example
add_subdirectory(hello_world)

add_compile_options(-Wall
        -Wno-format          # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int
        -Wno-unused-function # we have some for the docs that aren't called
        -Wno-maybe-uninitialized
        )

# Hardware-specific examples in subdirectories:
add_subdirectory(adc)
add_subdirectory(clocks)
add_subdirectory(cmake)
add_subdirectory(divider)
add_subdirectory(dma)
add_subdirectory(flash)
add_subdirectory(gpio)
add_subdirectory(i2c)
add_subdirectory(interp)
add_subdirectory(multicore)
add_subdirectory(picoboard)
add_subdirectory(pio)
add_subdirectory(pwm)
add_subdirectory(reset)
add_subdirectory(rtc)
add_subdirectory(spi)
add_subdirectory(system)
add_subdirectory(timer)
add_subdirectory(uart)
add_subdirectory(usb)
add_subdirectory(watchdog)

Dit alles heb ik me nog niet in verdiept. Allemaal chinees voor mij. (alhoewel ik redelijk snel de bedoeling van "add_subdirectory(pwm)" kan bedenken)

Ik heb nergens aangezeten, dit wordt zo in de "pico-examples" gedistribueerd.

Dus bovenstaand bestand kan je vinden:
https://github.com/raspberrypi/pico-examples/blob/master/CMakeLists.tx
(downloaden met de "raw" link rechtsboven).

Edit: Oh! die "-Wno-maybe-uninitialized" moet er uit wat mij betreft: die vangt zo nu en dan bugs bij mij. Bijvoorbeeld een tak A en B van een IF waarbij in de eerste instantie alleen tak A een variabele gebruikt. Die initializeer je dan netjes op 0 en dan ga je hem gebruiken. Om dingen bij mekaar te houden, doe je dat binnen tak-A. Als je nu later iets toevoegt dat je die variabele ook gebruikt in tak B...

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Dag rew,

We zijn er! 10MByte in circa 30 seconden. Knap werk, bedankt voor uw hulp.

Ten gerieve van eventuele andere lezers vat ik de essentie van het verhaal samen. Ik maakte de fout van bij de eerste kennismaking met "getting started with pico .." te vlug naar hoofdstuk 8 (het schrijven van een eigen C programma) over te stappen. Het lukte wat gpio en pwm te programmeren. Ook simpele berichtjes via USB lezen en schrijven lukte direct.

Zelf maak ik nooit met grote projecten. make en cmake heb ik enkel gebruikt bij installatie van software. Ze werden door anderen geschreven en ik begrijp lang niet alles wat in die files staat. Door direct over te stappen naar het schrijven van een eigen programma mist de compiler informatie die in verschillende (c)make files is verstopt.

Mijn tweede fout was te bouwen op de voorbeelden uit de USB map in pico-examples. Dat was niet nodig. Uw vertrekpunt vanuit "hello_world" is beter.

Moraal van het verhaal: Als pico beginner is het best te vertrekken vanuit de hele structuur van het voorbeeld dat best op de te programmeren code lijkt. Op die manier neem je heel de boom met hulpbestanden mee.

Omdat het forum zo goed heeft geholpen ga ik straks de navigatiebalk aan de linkerkant van het scherm opzoeken, de rubriek boven "Feedback".

Iedereen bedankt voor de gekregen hulp,

Vriendelijke groeten;

Eduard

Maar nu wil ik hiervan leren wat er in jou cmake files verkeerd was om het zo langzaam te krijgen. Mijn theorie dat je te veel aparte write calls genereert is dus kennelijk niet juist. Dan wil ik leren wat ik moet herkennen in de cmakefile als: "dat is de fout die eduard heeft gemaakt waardoor het langzaam wordt".

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Dag rew,

"De opgebouwde ervaring is evenredig met de hoeveelheid afgedankt materiaal" blijft nog steeds van toepassing. In ons geval is het afgedankt materiaal virtueel; een hoop bitjes en tijd.

Niet enkel de (c)make files verschillen maar ook de hierarchie der mappen is anders. De structuur van het Hello_Usb gaat een niveau dieper dan de eenvoudiger Blink. De (c)make files zijn niet enkel anders, er zijn er ook meer.

Als je mijn niet werkend programma wil samenstellen dan volg je de instructies van hoofdstuk 8 uit “Getting started”. De foute CmakeLists.txt staat in een vorige bijdrage. Op die manier kom je tot een langzame usb verbinding. De map waarin ik werkte noemde “test2” en die stond naast “pico-examples” en “pico-sdk”. Als het je helpt dan neem je via mail direct contact en dan stuur ik de zip van de betreffende mappen.

Vriendelijke groeten,

Eduard

Ik heb er werk in gestoken om jou probleem te debuggen. Inderdaad je hebt voldoende informatie gegeven dat ik zou moeten kunnen reproduceren dat ik ook een "langzaam" programma krijg.

Ik had gehoopt dat je mij een plezier zou kunnen doen door uit te zoeken wat er nu precies uitmaakt.

Mijn "compiler-en-programmeer-kennis" vertelt me dat in welke directory je de sources zet niet uit hoort te maken. Dus als ik naast mijn pico-examples directory een "hello-rew" directory aanmaak en daar de cmake stuff inzet die "cmake" tegenkomt als ie de hierarchie doorloopt bij mijn aangepaste voorbeeld, dan zou ik gewoon een identiek snel test-programma moeten krijgen.

Dus volgens mijn aannames kan het niet aan bepaalde dingen liggen. Maar dit soort foutzoeken wordt altijd zeer bemoeilijkt door aannames die fout blijken te zijn.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Eduard2

Honourable Member

Beste rew

Met plezier maak ik een "hello-rew" map naast de examples. Ik zal starten met daarin een CMakeLists.txt die alles bevat uit het snel werkend voorbeeld.

Als dat langzaam blijkt te werken dan verneem je dat via deze draad.

Werkt het snel dan ga ik de files uitdunnen tot het moment dat de snelheid zakt.

Ik hou je op de hoogte.

edit 20h40: Na een dagje proberen en herstarten staan 2 zipfiles voor u klaar. Hoe krijg ik die bij u ? De eerste bevat een map rew-examples. Dat is de eenvoudigste snel werkende verbinding. Unzippen en onder pico zetten en het zou moeten werken. Alles wat voor deze toepassing niet nodig was heb ik verwijderd. Mogelijk kan je nog verder uitdunnen.

De andere zip file is de traag werkende versie. Ook te plaatsen direct onder pico.

Verder vereenvoudigen lukt me niet omdat ik de instructies in de cmake en make niet altijd begrijp.

Vriendelijke groeten,

Eduard

[Bericht gewijzigd door Eduard2 op 14 juni 2021 20:53:19 (38%)]