eské vysoké u ení technické v Praze Fakulta elektrotechnická Studijní program: Elektrotechnika a informatika Obor: Výpo etní technika
Bakalá ská práce
Bezdrátový mikrofon Petr Mohelský Vedoucí projektu Ing. Miroslav Skrbek Ph.D.
Srpen 2007
1
2
Pod kování Tímto bych cht l pod kovat mému vedoucímu bakalá ské práce Ing. Miroslavu Skrbkovi Ph.D. za jeho ochotu a pomoc p i vypracovávání mého projektu.
3
4
Prohlášení Prohlašuji, že jsem tuto bakalá skou práci vypracoval samostatn a použil jsem pouze podklady uvedené v p iloženém seznamu. Nemám závažný d vod proti užití tohoto školního díla ve smyslu §60 Zákona .121/2000 Sb.. o právu autorském, o právech souvisejících s právem autorským a o zm n n kterých zákon (autorský zákon).
…………………………………. Ve Svobod nad Úpou dne 20. srpna 2007
Petr Mohelský
5
6
Abstrakt Tento projekt se zabývá návrhem a realizací softwaru pro stranu PC, která p ijímá data z kodeku p es Bluetooth a posílá je na zvukovou kartu, navrhuje možné ešení tohoto softwaru tak, aby se choval jako další zvuková karta a vytvá í software pro mikroprocesor dsPIC30F4013, který posílá data do obvodu UART. D ležitým faktorem ovliv ujícím tuto práci je pom rn vysoká kvalita p enášeného zvuku za ú elem dalšího zpracování. Proto, aby jsme dosáhli takové kvality zvuku, byla vytvo ena ADPCM komprimace v soub žné bakalá ské práci. Tento projekt vznikl ve spolupráci s firmou IBM v rámci studentských projekt : IBM - CVUT Student Research Projects.
Abstract This project deals with design and realization of PC side software that receives data through Bluetooth connection from codec and sends them to the sound card, designs posibilities of programming this software to behaves like another sound card, creates software for microprocessor dsPIC30F4013 that sends audio data to the UART circuit. The important factor affecting this assignment is relatively high quality of transferred sound in order to further processing. For achieving this quality of sound, in parallel bachelors work was created ADPCM comprimation. This project was created in cooperation with IBM company in frame of student projects: IBM - CVUT Student Research Projects.
7
8
Obsah Obsah............................................................................................................. 9 1. Úvod ......................................................................................................... 13 1.1 Úvod do projektu ................................................................................. 13 1.2 Specifikace cíle a popis projektu ......................................................... 14 1.2.1 Specifikace cíle ............................................................................. 14 1.2.2 Popis projektu ............................................................................... 14 1.3 Struktura bakalá ské práce.................................................................. 17 2. Teoretický úvod....................................................................................... 18 2.1 Popis ovlada e .................................................................................... 18 2.1.1 DriverEntry .................................................................................... 20 2.1.2 Obecný audio driver ...................................................................... 20 2.1.3 Specifikace topologie .................................................................... 21 2.2 Sériová komunikace ............................................................................ 22 2.2.1 Popis hardwaru sériového portu ................................................... 22 2.2.2 Princip sériové komunikace .......................................................... 23 3. Analýza a návrh implementace .............................................................. 24 3.1 Návrh implementace............................................................................ 25 3.2 Software na stranu PC......................................................................... 26 3.3 Program pro procesor dsPIC30F4013 ................................................. 27 3.4 Návrh implementace driveru................................................................ 28 4. Realizace projektu................................................................................... 31 4.1 Software pro PC .................................................................................. 31 4.1.1 Obsluha sériového portu ............................................................... 31 4.1.2 P ehrání zvuku .............................................................................. 33 4.1.3 Struktura funkce main()................................................................. 34 4.2 Program pro dsPIC30F4013................................................................ 35 5. Testování ................................................................................................. 38 5.1 Program pro procesor dsPIC30F4013 ................................................. 38 5.2 Aplikace obsluhy sériového portu a p ehrání zvuku ............................ 38 5.3 Test ovlada e Simple .......................................................................... 39 6. Záv r ........................................................................................................ 40
9
10
Literatura...................................................................................................... 41 Seznam obrázk .......................................................................................... 43 P ílohy.......................................................................................................... 44 A. Seznam zkratek .................................................................................... 44 B. Výpis zdrojových soubor program ..................................................... 45 B.1 Aplikace obsluhy sériového portu a p ehrání zvuku ........................ 45 B.2 Program pro procesor dsPIC30F4013 ............................................. 55 C. Obsah p iloženého CD.......................................................................... 58
11
12
1. Úvod 1.1 Úvod do projektu Cílem této bakalá ské práce je navrhnout a realizovat programové vybavení na stranu PC již hotového hardwarového ešení bezdrátového mikrofonu.(obr. 1) Tento software se má chovat jako další zvuková karta. Proto, abych dosáhl tohoto cíle, je nutné prostudovat zapojení bezdrátového mikrofonu. Dále pak naprogramovat software pro procesor dsPIC30F4013, který ovládá ást bezdrátového mikrofonu. St žejní ást této bakalá ské práce je navrhnout a realizovat aplika ní rozhraní na stranu PC, které využijí p ípadné další aplikace a toto rozhraní naprogramovat tak, aby tyto aplikace mohli p ijímat digitalizovaná data pro další zpracování. Takovým rozhraním m že být další zvuková karta nebo vhodn vytvo ená knihovna.
Obrázek 1: Zapojení bezdrátového mikrofonu (foto. Mohelský) Tento projekt vznikl ve spolupráci s firmou IBM v rámci studentských projekt
IBM - CVUT Student Research Projects. Má práce navazuje na
stejnojmennou bakalá skou práci, která se zabývala návrhem hardwarového
13
ešení bezdrátového mikrofonu na bázi technologie Bluetooth, jejímž úkolem bylo prozkoumat, zda je reálné p enášet zvuk pomocí této technologie. D ležitý faktor, jenž ovliv uje návrh a realizaci této práce, je dosáhnout pom rn
velké p enosové rychlosti, která nám dovolí p enášet
zvuk v dobré kvalit pro p ípadné další zpracování. Soub žn
s tímto projektem je zadána bakalá ská práce, která se
zabývá komprimací p enášených zvukových dat pro tento bezdrátový mikrofon.
1.2 Specifikace cíle a popis projektu 1.2.1 Specifikace cíle Cílem projektu je navrhnout a realizovat softwarové vybavení na stranu PC, které má za úkol p ijímat zvuková data z bezdrátového mikrofonu a následn tato data p eposlat na zvukovou kartu. Tento software bude ve form
aplika ního rozhraní. Je také pot eba vytvo it program pro procesor
dsPIC30F4013[4], který bude posílat digitalizovaná data z kodeku do BT modulu a ten je následn
bude p eposílat bezdrátov
pomocí technologie
Bluetooth do USB adapteru. Na zvuková data jsou kladeny požadavky, aby vzorkovací frekvence byla pokud možno 16 000 Hz a bitové kódování bylo 16 bitu. Dalším cílem této práce je prostudovat možnosti naprogramování tohoto softwaru tak, aby se již zmín ný bezdrátový mikrofon choval jako další zvuková karta. A dle možností tuto variantu naimplementovat.
1.2.2 Popis projektu Proto, abych mohl navrhnout a realizovat software pro bezdrátový mikrofon, je nejd íve nutné seznámit se s fyzickým zapojením. Jednotlivé komponenty bezdrátového mikrofonu byly zpracovány v p edešlé bakalá ské práci mého p edch dce.[6]
14
V této
podkapitole
jsou
krátce
popsány
jednotlivé
komponenty
bezdrátového mikrofonu a jejich fyzické propojení. Detailní popis jednotlivých komponent je umíst n v kapitole 3.1. Mikrofon je zapojen do kodeku. (obr. 2)
Obrázek 2: Kodek (p evzato z [6]) Kodek, který p evádí analogový signál na digitální, je zasunut do modulu dsPICDEM 2 [5], na kterém je umíst n krom
jiného i procesor
dsPIC30F4013 a sériové rozhraní RS-232.(obr. 3)
15
Obrázek 3: Zapojení kodeku a modulu dsPICDEM 2 (foto. Mohelský) BT modul, jenž je propojen s modulem dsPICDEM 2 pomocí sériového kabelu, obsahuje rozhraní RS-232 pro sériovou komunikaci. Dále pak obsahuje obvod F2M03AC2 [3], který slouží k bezdrátové komunikaci pomocí technologie Bluetooth a komunikuje tak s USB Donglem, který je zapojen do PC. (obr.4)
Obrázek 4: BT modul (p evzato z [6])
16
1.3 Struktura bakalá ské práce Tato podkapitola je ur ena k popisu struktury bakalá ské práce vzhledem k vyty eným cíl m. •
První kapitola je v nována úvodu do bakalá ské práce.
•
Druhá kapitola se zabývá teoretickým popisem d ležitých oblastí, kterých se tato práce dotýká. Je zde proto, aby tená lépe pochopil tuto bakalá skou práci a to zejména ást programování ovlada
, jenž
není p íliš známá. •
T etí kapitola popisuje analýzu a návrh implementace. V této ásti se provádí teoretický rozbor daného
ešení a to v etn
výb ru
vývojových nástroj a programovacího jazyka. •
tvrtá kapitola je popisem realizace projektu. Je psaná hlavn
jako
d kladná dokumentace programované aplikace. Naleznete zde detailní popis vytvo ených funkcí, stru ný popis funkcí použitých i popis struktury funkce main() této aplikace. •
Pátá kapitola je v nována testování funk nosti dané aplikace i virtuální zvukové karty.
17
2. Teoretický úvod 2.1 Popis ovlada e Pro návrh a implementaci virtuální zvukové karty je pot eba naprogramovat driver. Tato kapitola seznamuje
tená e nejd íve s tím jak
vypadá obecný driver a posléze popisuje audio driver. Programy v systémech Windows pracují ve dvou úrovních. První z nich je neprivilegovaná úrove , zvaná User mode. Na této úrovni leží aplikace, které si vysta í se službami API opera ního systému. Druhá z úrovní je privilegovaná, zvaná Kernel mode, v které pracuje jádro opera ního systému a jeho sou ásti, ke kterým pat í i ovlada e. Driver napsaný na této vrstv p istupuje na daný hardware v opera ním systému Windows XP pomocí ochranné vrstvy HAL (Hardware Abstraction Layer). [10] V systémech Windows 2000 a Windows XP je možné programovat dva druhy ovlada
a to tzv. Legacy ovlada e a PnP (Plug and Play). Legacy
driver je pojmenování zavedené od Windows 2000 pro starý typ driver , jenž nemají podpor
PnP ani Power Manager. Pro vytvo ení plnohodnotného
ovlada e PnP je zapot ebí, aby spl ovali požadavky WDM (Windows Driver Model), ke kterým pat í práv zmi ovaná podpora PnP a Power Maneger. Nemá-li driver tuto podporu, pak jej nazýváme Legacy driver. Takovýto ovlada je kompatibilní s Windows NT. [10]
18
Obrázek 5 : Kernel mode (p evzato z [10]) Driver je v tšinou spušt n p i startu po íta e. M že být spušt n i ru n
z podn tu uživatele. P i svém spušt ní zaregistruje adresy
obslužných rutin, které tvo í rozhraní mezi ovlada em a opera ním systémem. Prost ednictvím t chto rutin opera ní systém komunikuje s ovlada em. Pokud chce aplikace poslat požadavek ovlada i, musí k n mu nejprve vytvo it handle pomocí funkce CreateFile() s registrovaným jménem. Pomocí tohoto handlu jsou ovlada i posílány požadavky. Ty se p es rozhraní API dostanou k I/O Manageru (obrázek .3), jenž z nich vytvo í pakety IRP, které posílá ovlada i. Po vy ízení požadavku je IRP ozna en jako hotový a je do n j uložen výsledek . I/O Manager jej poté pošle zp t aplikaci.
I/O
operace s fyzickým za ízením jsou vykonávány p es ochrannou vrstvu HAL.[10]
19
Obrázek 6 : Zpracování IRP (p evzato z [10])
2.1.1 DriverEntry DriverEntry je základní rutinou každého ovlada e (Obdoba main() metody v programovacím jazyku C). Ta je ovládána I/O Managerem ihned po spušt ní driveru. DriverEntry nastavuje ukazatele na tzv. Dispatch obslužné rutiny reprezentující vstupní body obslužných funkcí pro ovlada e WDM.[10]
2.1.2 Obecný audio driver Ve Windows XP je k naprogramování použit p ístup WDM a KS (Kernel Streaming) komponenty, které operují v Kernel módu a jsou sou ástí opera ního systému. Je dobré si uv domit, že mluvíme o naprogramování driveru, který je složen z n kolika díl ích driver , které navzájem spolupracují. Postup je takový, že programátor implementuje pouze tzv.
20
miniport driver, který vždy spolupracuje s p íslušným port driverem. U audio driveru je tomu tak, že si vždy zvolíme jeden ze t í port driveru. Máme na výb r z : WaveCyclic port driver, WavePci port driver a WaveRT driver, jenž nabízí systémový ovlada
PortCls. Ovlada
WaveRT lze použít pouze u
systému Windows Vista.[7]
2.1.3 Specifikace topologie Topologie
logicky
popisuje
strukturu
zvukové
karty
vzhledem
k driver m. KS topologie je složena ze set datových struktur, které popisují logické cesty pro proudy audio dat. Tyto struktury jsou uzly, piny a filtry, které mají vlastnosti p ístupné uživateli. Uživatelem je zde myšlen kernel driver nebo aplikace.[7] Zvukový filtr je tvo en práv již zmín nými wave miniport a wave port drivery. Každý wave miniport ovlada implementuje specifické funkce filtru za ízení. Obsahuje definici ásti topologie zvukové karty. Wave port driver má na starost obecné operace s filtry a také se stará o komunikaci s opera ním systémem.[7] Každý filtr má jeden nebo více KS pin , které slouží jako logická cesta vstupním nebo výstupním proud m zvukových dat. Uzel je datová struktura, jenž popisuje vnit ní topologii filtru. Takovým p íkladem uzlu je ovládání hlasitosti.[7] Celková topologie obecné zvukové karty je složena ze t í d ležitých filtr : MIDI filtr, Topology filtr a WaveXxx filtr. Xxx zde znamená Pci, RT nebo Cyclic. Topology filtr ídí
ást obvod
zvukové karty a mixuje dohromady
proudy zvukových dat. MIDI filtr representuje MIDI za ízení. WaveXxx filtr má na starosti p evod analogového signálu na digitální a naopak.[7]
21
Obrázek 7 : Topologie obecné zvukové karty (p evzato z [7])
2.2 Sériová komunikace Protože se USB adaptér chová z hlediska po íta e jako sériová linka, je v této ásti popsána teorie sériové komunikace.
2.2.1 Popis hardwaru sériového portu Pro sériovou komunikaci se používají signály, jenž m žeme z hlediska jejich funkce rozd lit do dvou r zných skupin. První skupinou jsou signály pro p enos vlastních dat. T mito signály jsou TxD pro vysílaní a RxD pro p íjem dat. Druhou skupinou jsou tzv. signály modemu pro p íjem dat. Tyto signály p enášejí informace o stavu vysíla e a p ijíma e. Jsou to signály RTS, CTS, DSR, DTR.[11]
22
2.2.2 Princip sériové komunikace P i vysílaní znaku jsou data nahrána z registru Transmiter Holding Registr do posuvného registru vysíla e a bit po bitu jsou posílána na výstup jako signál TxD. Struktura jednoho rámce dat na p i sériové komunikaci je následující: První bit je nazván p ízna n
START BIT. Následuje 5 až 8
datových bit . Dále pak následuje PARITY BIT, který m že, ale také nemusí, být zahrnut v datovém rámci. A na konci rámce jsou STOP BITS, které mohou být jeden, jeden a p l nebo dva. START a STOP bity jsou ur eny k synchronizaci jednoho rámce. P ijíma
p i sériové komunikaci o ekává
p ijímané bity jako signál RxD a ve svém posuvném registru z nich skládá p ijatý znak. Po p ijetí posledního bitu uloží rámec do registru Receiver Buffer Register, ze kterého je poté odebrán k dalšímu zpracovaní.[11]
Obrázek 8 : Struktura p enášeného byte (p evzato z [2]) Vlastní obvod pro sériovou komunikaci tvo í zpravidla obvod UART 8250, a to u starších typ
po íta
, nebo obvod 82550 u nov jších typ .
N které obvody UART vzorkují vstup RxD ty násobnou rychlostí a provád jí vyhodnocení odebraných vzork
dva ze t í. Tím jsou eliminovány krátké
poruchy nebo rušení v p enosu dat.[11]
23
3. Analýza a návrh implementace Blokové schéma cílového ešení bezdrátového mikrofonu je na obr. 9. Bloky ozna ené mod e jsou existující hardwarové komponenty, zelen ozna ené komponenty byly navrženy a implementovány v rámci této BP. Hlavní ást práce leží na stran PC, kde bylo nutné vy ešit návrh a realizaci softwaru pro p íjem dat ze sériové linky a softwaru, který by um l zvuková data p ehrát. Další d ležitou ástí bylo navrhnout a dle možnosti realizovat virtuální audio driver, jenž má sloužit jako další aplika ní rozhraní pro p ípadné další programy, a software pro procesor dsPIC30F4013, který p ijímá digitální data z kodeku a posílá je p es sériovou linku do BT modulu. (Ten je pak následn pošle do PC.)
Obrázek 9 : Zapojení bezdrátového mikrofonu (obr. Mohelský) Následuje popis jednotlivých komponent: Mikrofon zapojený do kodeku snímá zvuk z okolního prost edí. Kodek, který je zapojen do modulu dsPICDEM 2, p evádí zvukový signál do digitální formy. M že se také chovat
24
jako výstupní za ízení, tedy m že p evést digitální signál zpátky na analogový. Obsahuje 4 I/O konektory : Analogový vstup, analogový výstup, line in a line out. Dále obsahuje rozhraní pro komunikaci s procesorem dsPIC30F4013. [6] Na modulu dsPICDEM 2 je umíst n již zmín ný procesor, obvod UART pro sériovou komunikaci a krom
jiného i RS-232 sériový port. Pro
procesor je pot eba naprogramovat program tak, aby posílal zvuková data p ijatá z kodeku na sériovou linku.[6] BT modul, který je spojen s deskou dsPICDEM 2 pomocí sériového kabelu, je ur en pro p enos dat p es BT kanál a zárove dokáže poslat až t i PCM signály. Obsahuje RS-232 sériový port, obvod UART a za ízení F2M03AC2, které je ur eno k bezdrátovému vysílání dat. [6] USB adaptér zapojený do PC p ijímá data vyslaná BT modulem. P estože je zapojen do USB konektoru, chová se z hlediska PC jako sériová linka.
3.1 Návrh implementace Existují r zné možnosti, jak vy ešit naprogramování softwaru na stranu PC: První variantou je, že data poslaná z BT modulu do USB adaptéru, který se chová jako sériová linka, jsou p ijata do aplikace vytvo ené pomocí funkcí WIN 32 API. Následn jsou tato data poslána p ímo na zvukovou kartu pro p ehrání.(obr.10)
Obrázek 10: Komunikace p es WIN 32 API (obr. Mohelský)
25
Druhou možností, jenž se nabízí, je naprogramovat virtuální audio driver, který bude p ijímat data ze sériové linky (na úrovni driveru) a vytvo it aplika ní rozhraní pro tento driver pro p ípadné další aplikace.(obr.11)
Obrázek 11: Komunikace p es virtuální audio driver (obr. Mohelský) T etí varianta je naprogramování knihovny DLL, která by p ijímala data poslaná BT modulem ze sériové linky a vytvo ila by aplika ní rozhraní pro programy.
Obrázek 12: Komunikace p es DLL knihovnu (obr. Mohelský)
3.2 Software na stranu PC Jak již bylo d íve zmín no, chová se USB adaptér z hlediska osobního po íta e jako sériová linka. Pro p íjem dat ze sériové linky pod opera ním systémem Windows XP, který byl zvolen jako systém, pod kterým bude bezdrátový mikrofon fungovat, je tedy pot eba naprogramovat rozhraní, jenž bude um t tato data p ijmout. U opera ních systém
MICROSOFT WINDOWS 32 rozlišujeme
platformu 9.X a NT. Platforma 9.X nám umož uje p ímý p ístup na ídící
26
registry periferií a vystavuje se tak nebezpe í, že tato periferie je již využívaná jiným vzájemn b žícím programem, což m že vést k nestabilit celého opera ního systému. Já však zvolím platformu na bázi NT, která je založena na ochranném módu procesoru. V tomto módu je možné p istupovat do I/O adresového prostoru pouze p es aplika ní interface a p es ovlada dané periferie. Je tedy nutné naprogramovat obsluhu sériového portu COM s využitím API služeb jádra opera ního systému MICROSOFT WINDOWS 32. K napsání toho softwaru mám na výb r z n kolika programovacích jazyk . Velmi vhodný, pro jeho rozší enost a efektivnost, je programovací jazyk C/C++ s vývojovým prost edím Microsoft Visual Studio 6.0. Existují sice i jiné možnosti, hlavn
p i výb ru vývojových prost edí, ale ta nijak zásadn
naprogramování tohoto softwaru neovlivní. Hlavní funkce tohoto softwaru spo ívá v p ijmu zvukových dat ze sériové linky. Je proto nutné vytvo it funkce s použitím WIN 32 API, které na tou data do p íslušného bufferu. Ten pak bude k dispozici k p ípadnému dalšímu zpracování.
3.3 Program pro procesor dsPIC30F4013 Pro vytvo ení programu ovládajícího procesor dsPIC30F4013 je pot eba vývojové prost edí MPLAB IDE s doinstalovaným p eklada em MPLAB C30, jenž mi umožní napsání tohoto softwaru v programovacím jazyku C. Z požadovaných parametr zvuku, které jsou 16 bitové kódování a 16 kHz vzorkovací frekvence, vyplývá, že pot ebuji nastavit p enosovou rychlost nejmén na 256 000 baud . Sériové rozhraní RS-232 modulu dsPICDEM 2 lze programov nastavovat až do rychlosti 921 600 baud . Sériové rozhraní RS-232 BT modulu lze taktéž nastavovat až do rychlosti 921 600 baud . Z teoretického hlediska by tedy tato rychlost m la sta it.[3,4]
27
Hlavní funkcí tohoto programu je p íjímání digitálních dat z kodeku, digitalizace t chto dat, pokud to bude pot eba, a poslání t chto dat p es sériovou linku do BT modulu.
3.4 Návrh implementace driveru Proto, aby se daný software choval jako další zvuková karta, je zapot ebí naprogramovat virtuální audio driver. Nástrojem pro tvorbu ovlada
v opera ních systémech Windows je WDK (Windows Driver Kit).[7]
Bohužel pro tvorbu virtuálního audio driveru je k dispozici jen velmi málo materiál . Proto dobrým ešením tohoto problému je p ed lat již hotový virtuální audio driver. V dokumentaci od WDK je ada hotových p íklad
ozna ených pod
souhrnným názvem MSVAD (Microsoft Virtual Audio Driver). Následuje výpis již hotových virtuální driver : •
Simple - základní driver s WaveCyclic a Topology port ovlada i
•
Multistr - implementuje vícenásobné p ehrávaní stream
•
Drmsimp - implementuje DRM (Digital Rights Management) pro Simple driver
•
Drmmult - implementuje DRM pro Multistr driver
•
Pcmex - implementuje WAVEFORMATEXTENSIBLE piny
•
Ac3 - implementuje AC3 piny pro p ehrávání
•
Ds2dhw - implementuje DirectSound 2D podporu Z t chto napsaných driver
se pro ešení našeho problému nejlépe
hodí driver nazvaný Simple pro jeho jednoduchost. Tento ovlada
je
základem pro všechny ostatní ovlada e. U ostatních typ
je
ovlada
podpora pro funkce, které nepot ebujeme. Struktura Simple driveru je rozd lena na dv základní ásti. První ást je spole ná pro všechny typy výše zmín ných ovlada
. Druhá
ást je
28
specifická
podle
druhu
ovlada e.
Ovlada
je
naprogramován
v programovacím jazyku C++. Následuje popis spole né ásti :[7] adapter.cpp - spojuje ovlada s opera ním systémem basedma.cpp - implementace IDmaChannel basetopo.cpp - implementace rodi ovské topology t ídy basetopo.h - definice rodi ovské topology t ídy basewave.cpp - implementace rodi ovské waveCyclic t ídy basewave.h - definice rodi ovské waveCyclic t ídy common.cpp - spole ný objekt využit všemi miniport ovlada i common.h - header soubor pro spole ný objekt hw.cpp - hardwarová abstrakce MSVAD hw.h - definice hardwarové t ídy kshelper.cpp - implementace funkcí kernel streaming utilit kshelper.h - definice funkcí kernel streaming utilit msvad.h - spole né definice pro MSVAD msvad.inf - instala ní INF soubor pro tento ovlada msvad.rc - spole ný resource soubor readme.htm - dokumentace savedata.cpp - zapsání PCM dat na disk savedata.h - definice trídy CSaveData sources.inc - spole ný zdrojový soubor vložený do všech ovlada Následuje popis souboru pro ovlada Simple: Makefile - standardní DDK make soubor mintopo.cpp - implementace miniport topology driveru mintopo.h - definice miniport topology driveru minwave.cpp - implementace miniport wavecyclic ovlada e minwave.h - definice miniport wavecyclic ovlada e readme.htm - dokumentace simple.h - spole né deklarace pro celý ovlada Simple sources - standardní zdrojový soubor DDK
29
toptable.h - popis topology miniport ovlada e wavtable.h - popis wave miniport ovlada e Po prostudování t chto soubor se dá usoudit, že ovlada je složen z Topology filtru a WaveCyclic filtru, jenž jsou popsány v teoretické
ásti.
Ovlada zastává funkci klasické reálné zvukové karty, tedy p ijímá zvuk ze všech b žících aplikací a opera ního systému. Protože nemá reálný výstup, simuluje ukládaní všech zvuk namixovaných do sebe do souboru. Z této skute nosti vyplývá, že mám dv možnosti jak upravit ovlada Simple do podoby, aby p ijímal zvuková data ze sériové linky. První z nich je využití softwaru pro sériovou linku a softwaru, který posílá data na zvukovou kartu. P i využití této možnosti je nutné naimplementovat ovlada tak, aby identifikoval tento software a p ijímal zvuková data pouze z n j. Druhá možnost je doprogramovat ovlada , aby p ímo bral data ze sériové linky, tedy ne p es vytvo enou aplikaci. První z možností se zdá být jednodušší, avšak druhá efektivn jší. P i druhé z možností je pot eba odstranit ásti ukládání audio dat na disk, tedy odstranit soubory savedata.cpp a savedata.h. P ed lat WaveCyclic filter, aby p ijímal data ze sériové linky (na úrovni driveru) a odstranit z n j ást, kde p evádí analogový signál na digitální. Tedy upravit soubory miniwave.cpp a miniwave.h. Odstranit nepot ebné ásti Topology filtru a to: Vstup pro mikrofon, výstup pro reproduktory a p ípadné další
ásti. Tedy
upravit soubory minitopo.cpp a minitopo.h. V prvním p ípad by byl postup podobný, až na ást p ijmu dat ze sériové linky na úrovni driveru.
30
4. Realizace projektu Tato kapitola popisuje software vytvo ený pro PC, který se d lí na dv ásti: Aplikaci, která obsahuje funkce pro p ehrání zvuku, funkce pro obsluhu sériové linky a hlavní funkci main() (Tento software dokáže p ijmout data ze sériové linky a tato data p ehrát.) a na virtuální audio driver. Dále tato kapitola popisuje program pro procesor dsPIC30F4013.
4.1 Software pro PC 4.1.1 Obsluha sériového portu Protože se USB adaptér vzhledem k PC chová jako sériová linka, je nutné realizovat software pro p íjem zvukových dat ze sériové linky. Ve WIN 32 se hledí na sériový port jako na otev ený soubor, který m že být zárove otev en pro tení a zárove pro zápis. Proto musím vytvo it handle sériového portu pomocí funkce CreateFile(). Pro oboustranný p ístup k sériovému portu je nutné handle vytvo it s parametry GENERIC_READ a GENERIC_WRITE. Sériový p enos rozlišuje dva módy a to synchronní (nonoverlapped) a asynchronní (overlapped). Rozdíl mezi t mito módy je ten, že funkce pro tení nebo zápis jsou opušt ny pouze v okamžiku odeslání posledního požadovaného bitu. Nevýhodou tohoto módu je to, že zastaví všechny další b žící operace, které se týkají obsluhy sériového portu a tím vytvá í poloduplexní p enos. Asynchronní mód, který je implementován i v programu pro obsluhu sériového portu bezdrátového mikrofonu, umož uje pln duplexní p enos dat. Pro asynchronní p enos dat je nutné nastavit p i vytvá ení handlu sériového portu parametr funkce CreateFile() na hodnotu FILE_FLAG_OVERLAPPED.
Následuje
popis
vytvo ených
funkcí
pro
obsluhu sériové linky . [11]
•
CreateHandle() - funkce vytvo í handle pro p ístup k vlastnímu portu
31
•
SetCommunicationTime() - funkce nastaví time-out parametr komunika ního za ízení. Všechny parametry jsou typu DWORD. První parametr ur uje maximální dobu v milisekundách mezi dv ma po sob
p íchozími znaky p i operaci
tení. Je-li tato doba
p ekro ena, operace je p ed asn ukon ena. Druhý parametr ur uje dobu v milisekundách, která je násobena po tem o ekávaných byte, pro výpo et celkové p edpokládané doby operace parametr
ur uje
konstantu
v milisekundách
tení. T etí
pro
výpo et
p edpokládané doby operace tení, která je p i tena k dob
dané
parametrem ReadTotalTimeoutMultiplier (druhý parametr).
tvrtý
parametr ur uje dobu v milisekundách, která je násobena po tem vyslaných byte, pro výpo et celkové p edpokládané doby operace vysílání. Pátý parametr ur uje konstantu v milisekundách pro výpo et p edpokládané doby operace vysílání, která je p i tena k dob
dané
parametrem
WriteTotalTimeoutMultier
( tvrtý
parametr).
•
ConfigurePort() - Funkce nastaví pracovní parametry sériového portu. První parametr je typu DWORD a nastavuje p enosovou rychlost. Druhý parametr je typu BYTE a ur uje po et datových bit jednoho byte. M že mít hodnotu 5 až 8. T etí parametr je typu DWORD a ur uje spušt ní kontroly parity. Je-li hodnota tohoto parametru TRUE je spušt na kontrola parity.
tvrtý parametr je typu
BYTE a ur uje typ použité parity pro p enos. M že mít tyto hodnoty: EVENPARITY - sudá parita, MARKPARITY - st ídavá parita, NOPARITY – bez parity, ODDPARITY – lichá parita. Pátý parametr je typu BYTE a ur uje po et stopbit . M že mít tyto hodnoty: ONESTOPBIT – 1 stopbit,
ONE5STOPBIT – 1,5 stopbitu.
TWOSTOPBIT – 2 stopbity. •
Write() - funkce zapíše požadovaný po et byt do sériového portu. První parametr je pole char , které slouží jako buffer, jenž bude
32
poslán do sériového portu. Druhý parametr je typu DWORD a slouží k ur ení velikosti bufferu. •
Read() - funkce p e te požadovaný po et byt ze sériového portu. První parametr je pole char , které slouží jako buffer, do n hož budou znaky ukládány. Druhý parametr je typu DWORD a slouží k ur ení velikosti bufferu.
•
SetSerialPort() - nastavení masky sériového portu.
Stru ný popis d ležitých funkcí a struktur použitých v programu a definovaných ve WIN 32 API naleznete v p íloze B.1. Dále v této p íloze naleznete ukázku použití t chto funkcí.
4.1.2 P ehrání zvuku Z daného problému vyplývá nutnost posílaní dat na zvukovou kartu. Pro
ú ely
vy ešení
tohoto
problému
standardních funkcí WIN 32 API.
byla
zvolena
metoda
použití
innost t chto funkcí je založena na
principu zasílání zvuku na zvukovou kartu v podob blok dat. Pro plynulost p ehrávání není možné mít pouze jeden blok dat, protože prodleva mezi napln ním a p ehráním by zp sobila sice malé, ale p esto velmi nep íjemné pomlky v p ehrávání daného zvuku. V programu je vytvo ena fronta blok . Bloky jsou postupn
napl ovány a posílány do fronty. Mezi tím, kdy jsou
jeden i více blok dat zasílány k p ehrání, jsou ostatní dle pot eby pln ny. K tomuto ú elu jsou v programu definované konstanty: BLOCK_SIZE, jenž ur uje velikost jednoho bloku a BLOCK_COUNT, která vymezuje po et takto použitých blok . Z nastín ného postupu vyplývá nutnost pamatovat si po et prázdných blok , jenž je ur en prom nnou waveFreeBlockCount. Následuje popis vytvo ených funkcí použitých p i práci se zvukovou kartou.[6] •
writeAudio() - funkce slouží k zasílaní dat na zvukovou kartu. Prvním parametrem je prom nná typu HWAVEOUT. Druhým parametrem je
33
ukazatel na data, která se mají p ehrát. T etím parametrem je prom nná typu int, která ur uje velikost p ehrávaných dat. •
allocateBlocks() - funkce slouží k alokovaní pot ebného množství místa v pam ti po íta e pro bloky zvukových dat. První parametr je typu int a je jím p edávaná velikost jednoho bloku dat. Druhý parametr je typu int a je jím p edávaný po et blok .
•
freeBlocks() - funkce slouží k dealokování místa v pam ti zapln né zvukovými daty. Jediným parametrem funkce je ukazatel typu WAVEHDR*. Tímto parametrem p edáváme do funkce ukazatel na blok zvukových dat.
Stru ný popis d ležitých funkcí a struktur použitých v programu a definovaných ve WIN 32 API naleznete v p íloze B.1. Dále v této p íloze naleznete ukázku použití t chto funkcí.
4.1.3 Struktura funkce main() Tato podkapitola popisuje d ležité ástí funkce main() aplikace , která p ijímá data ze sériového portu a následn
je posílá na zvukovou kartu
k p ehrání. Protože se b hem realizace ukázalo, že je pot eba zvuk komprimovat, jsou k aplikaci p idané p íslušné knihovny. Zvolený druh komprimace je ADPCM. (Detailní popis této komprimace naleznete v soub žn zpracovávané bakalá ské práci [9]) Následuje popis d ležitých ásti funkce main(): •
nastavení parametr zvuku na 16000 Hz vzorkovací frekvence a 16 bitového kódovaní pomocí struktury WAVEFORMATEX
•
inicializace zvukového za ízení pomocí funkce waveOutOpen()
•
vytvo ení handlu sériového portu funkcí CreateFile()
•
nakonfigurování sériového portu funkcí ConfigurePort(). Sériový port byl nastaven na hodnoty: P enosová rychlost 115200 baud , po et datových bitu 8, žádná parita a 1 stop bit
34
•
nastavení
asových závislostí funkcí SetCommunicationTime().
První parametr ur uje maximální dobu v milisekundách mezi dv ma po sob
p íchozími znaky p i operaci
tení. Tento parametr je
nastaven na hodnotu 1000. Ostatní parametry jsou nastaveny na 0 •
následuje cyklus while. V tomto cyklu je obsažena funkce Read(), která na te do p ijímacího bufferu p íslušná data. Dále pak ADPCMDecoder(), která dekóduje p ijatá data a nakonec funkce writeAudio(), jenž pošle data k p ehrání na zvukovou kartu. ást kódu funkce main():
/*hlavní cyklus programu*/ while(1) {
}
Serial->Read((char*)buffer,sizeof(buffer)); /*ctení ze sériové linky*/ for(int i = 0;i<1024;i++){ code = buffer[i]; sample = (short)ADPCMDecoder((code>>4)&0x0f,&state_decoder); /*dekomprimace*/ /*p ehrání*/ writeAudio(hWaveOut, (char *)&sample, sizeof(short)); sample = (short)ADPCMDecoder((code)&0x0f,&state_decoder); writeAudio(hWaveOut, (char *)&sample, sizeof(short)); }
Ukázku struktury celé funkce main() naleznete v p íloze B.1.
4.2 Program pro dsPIC30F4013 Jak již bylo d íve e eno, pro p enos dat ze sériové linky modulu dsPICDEM2 je pot eba naprogramovat procesor dsPIC30F4013, který ídí zasílaní zvukových dat p es sériový kabel do BT modulu. K tomuto ú elu bylo nutné rozší it již hotový program, který p ijímal zvuková data pomocí rozhraní DCI z kodeku, o funkce, které posílají data na sériovou linku. (Na tení dat z rozhraní DCI lze provést pomocí funkce ReadDCI(i).) Protože
35
hodnota jednoho vzorku je 16 bitu a funkce umož ující poslat data na sériovou linku zasílá pouze 8 bitu, bylo pot eba danou 16 bitovou hodnotu rozd lit na dv
ásti pomocí bitových operací. Po rozd lení 16 bitové
hodnoty
data
jsou
ADPCMEncoder())
a
komprimována následn
ADPCM
poslána
na
komprimací
sériovou
linku
(funkcí (funkcí
WriteUART1()). Následuje stru ný popis d ležitých funkcí ídícího programu procesoru dsPIC30F4013. [1] •
OpenDCI() - funkce nakonfiguruje DCI
•
CloseDCI() - funkce vypne DCI
•
DataRdyDCI() - funkce vrací status, o tom je-li DCI buffer napln n daty a je-li p ipraven ke
tení. Pokud je p ipraven, funkce vrací
hodnotu 1 •
WriteUART1() - funkce pošle znak na sériovou linku
•
BusyUART1() - funkce vrací status, o tom je-li UART zaneprázdn n. Je-li zaneprázdn n vrací hodnotu 1
•
OpenUART1() - funkce nakonfiguruje sériovou linku
Ukázka asti kódu funkce main() tohoto programu: while (1) {
if (DataRdyDCI()) { if (full) { LATB |= 0b01; } else { for(i = 0; i < 4; i++) { buffer[i] = ReadDCI(i);/*nacteni audio dat*/ } if(send == false){ /*komprimace*/ code = ADPCMEncoder(buffer[0],&state_coder); code = (code << 4) & 0xf0; code2 = ADPCMEncoder(buffer[2],&state_coder); code = code | code2 ; send = true; } if(!BusyUART1() && send){ LATB |= 0b01; WriteUART1(code);
36
}
}
}
} full = 1;
send = false;
Stru ný popis d ležitých funkcí použitých v programu a jejich p íklad
naleznete v p íloze B.2.
37
5. Testování 5.1 Program pro procesor dsPIC30F4013 Nejd íve bylo nutné otestovat funk nost programu, jenž ovládá procesor dsPIC30F4013 a který posílá zvuková data na sériovou linku umíst nou na modulu dsPICDEM 2 pro tento procesor. Toho bylo dosaženo p ímým spojením s PC p es sériový kabel a s použitím programu Hyperterminál, jenž zobrazuje p ijatá data ze sériové linky. Program HyperTerminál je standardní výbavou opera ního systému Windows XP. P i tomto testu byla nejvyšší rychlost, které se dalo dosáhnout, nastavena na 115200 baud . V tší rychlost bohužel nebyla možná, protože obvody zabudované v sériovém portu to neumož ují. Bylo z ejmé, z p ijatých znak do programu Hyperterminal, že program vysílá velké množství dat na sériovou linku. Dále bylo nutné vyzkoušet, zda BT modul p ijímá zvuková data z modulu dsPICDEM 2 a následn je p eposílá do USB adaptéru. Toho jsem op t dosáhl pomocí programu Hyperterminál. Do rychlosti 230400 baud fungovalo posílání dat bez problému. P i rychlosti 460800 baud
však
komunikace nefungovala. Jak již bylo zmín no, pro p enos zvuku byla pot eba rychlost 256 000 baud . Bylo tedy nutné zabudovat komprimaci, jenž byla vytvá ena v soub žné bakalá ské práci.
5.2 Aplikace obsluhy sériového portu a p ehrání zvuku Dalším krokem bylo otestování celé aplikace, která p ijímá data ze sériové linky, poté pot ebná data dekomprimuje a následn
je pošle na
zvukovou kartu. Aplikace byla p i testování pln funk ní. P i poslechu zvuku byl daný zvuk plynulý a z etelný.
38
Celý test se dá zopakovat následujícím zp sobem: •
Naprogramovat procesor dsPIC30F4013.
•
Nakonfigurovat BT modul na stejnou rychlost jako je programov nastavena sériová linka dsPICDEM2. V našem p ípad
230 400
baud . •
Zapojit BT USB adapter do PC a nainstalovat ovlada e k tomuto za ízení.
•
Spustit aplikaci obsluhy sériového portu.
Zmín ná aplikace je sou ástí p iloženého CD.
5.3 Test ovlada e Simple P i testování driveru zvaném Simple se potvrdily moje p edpoklady popsané v analýze. Driver simuloval innost reálné zvukové karty. P ijímal zvuková data z b žících aplikací a opera ního systému a ukládal data do souboru . Popis p ekladu ovlada e: Pro p eklad ovlada e je nezbytné mít nainstalované prost edí WDK, ve kterém je pot eba spustit soubor s názvem “ Win XP Free Build Enviroment “. Po spušt ní tohoto souboru se otev e konsole, do které je pot eba napsat p íkaz build. Tím je p eklad u konce a následuje b žná instalace ovada e.
39
6. Záv r P i vypracování projektu bylo úsp šn
dosaženo t chto cíl :
Naprogramovat funk ní aplikaci pro stranu PC, která p ijímá zvuková data z kodeku p es BT a posílá tato data na zvukovou kartu. Realizovat program, který vykonává procesor dsPIC30F4013 a posílá tak zvuková data z kodeku p es sériové rozhraní do BT modulu. P itom se poda ilo zachovat požadavky kladené na zvuk, které jsou 16 bitové kódování a 16000 Hz vzorkovací frekvence. Tyto požadavky se povedly realizovat zásluhou ADPCM komprimace vytvo ené v kooperující bakalá ské práci. Dále se povedlo navrhnout a zprovoznit audio driver, který se chová jako další zvuková karta. P i ešení bakalá ské práce se nepoda ilo dovést implementaci virtuální zvukové karty do úplného konce z d vod
asové náro nosti. Implementace
byla zastavena po domluv s vedoucím práce. Jak lze pokra ovat v projektu? Doplnit ásti driveru Simple o sériovou komunikaci (na úrovni driveru), odstranit nepot ebné ásti tohoto ovlada e, naprogramovat p íslušné API a dovést tak myšlenku tohoto projektu do konce.
40
Literatura [1]
16bit language tools libraries. Microchip Technologie Inc. ,2005. URL:
[2]
Analýza d j rozhraní RS 232C. Brno: VUT, Fakulta informa ních technologií. URL:
[3]
Class 2 Bluetooth module – F2MO3AC2 datasheet. Free2move, 2005. URL:
[4]
dsPIC30F Family Reference manual. Microchip Technologie Inc,2006. URL:
[5]
dsPICDEM 2 Users Guide. Microchip Technologie Inc, 2005. URL:
[6]
Hrbek, Libor : Bezdrátový mikrofon. Bakalá ská práce. Praha: eské vysoké u ení technické, Elektrotechnická fakulta, katedra Po íta , 2006.
[7]
Microsoft Developer Network – Windows Driver Kit. Microsoft. URL:
[8]
Overton, David : Playing Audio in Windows using waveOutInterface. 2002. URL:
[9]
P ibyl, Michal : Kompresní algoritmus pro bezdrátový mikrofon. Bakalá ská práce. Praha: eské vysoké u ení technické, Elektrotechnická fakulta, katedra Po íta , 2006.
[10]
Trnka, Pavel : Profibus DP Master na PC. Diplomová práce . Praha : eské vysoké u ení technické, Elektrotechnická fakulta, katedra ídící techniky, 2004.
41
[11]
Václav, Vacek : Sériová komunikace ve WIN 32. Praha, Technická literatura BEN, 2003, ISBN 80-7300-086-5.
42
Seznam obrázk 1.Zapojení bezdrátového mikrofonu(foto.)……………………………………..13 2.Kodek…………………………………………………………………………….15 3.Zapojení kodeku a modulu dsPIC30F4013…………………………………..16 4.BT modul…………………………………………………………………………16 5.Kernel mod………………………………………………………………………19 6.Zpracování IRP………………………………………………………………….20 7.Topologie obecné zvukové karty…………………………………………...…22 8.Struktura p enášeného byte………………………………………………...…23 9.Zapojení bezdrátového mikrofonu(obr.) …………………..…………...……24 10.Komunikace p es WIN 32 API……………………………………………….25 11.Komunikace p es virtuální audio driver………………………………..……26 12.Komunikace p es DLL knihovnu…………………………………………….26
43
P ílohy A. Seznam zkratek API
Application Programming Interface
BT
Bluetooth
HAL
Hardware Abstraction Layer
KS
Kernel Streaming
MSVAD
Microsoft Virtual Audio Driver
IRP
I/O Request Packet
PnP
Plug and Play
USB
Universal Seriál Bus
WDK
Windows Driver Kit
WDM
Windows Driver Model
44
B. Výpis zdrojových soubor program B.1 Aplikace obsluhy sériového portu a p ehrání zvuku Následuje stru ný popis d ležitých funkcí a struktur použitých v programu a definovaných ve WIN 32 API pro soubor audio.cpp :
•
waveOutPrepareHeader() - funkce p ipravující buffer pro vstupní zvukové za ízení
•
CALLBACK waveOutProc() - funkce je volána opera ním systémem ve 3 p ípadech. P i za átku práce se zvukovou kartou. P i skon ení práce se zvukovou kartou. P i vyprázdn ní bloku dat. První dva p ípady jsou programov ignorovány.
•
waveOutUnprepareHeader() - funkce odstra ující buffer p ipravený funkcí
•
waveOutPrepareHeader() - funkce p ipravující buffer
•
waveOutOpen() - funkce otevírající dané výstupní zvukové za ízení pro p ehrávání
•
waveOutClose() - funkce uzavírající dané výstupní zvukové za ízení
•
waveOutWrite() - funkce zasílající blok dat na výstupní zvukové za ízení
•
WAVEHDR - struktura definující hlavi ku, která je užívána k ur ení parametr zvukového bufferu
•
WAVEFORMATEX - struktura pro nastavení parametr zvuku
Audio.cpp #include "StdAfx.h" #include "audio.h" /* funkce slouží k zasílaní dat na zvukovou kartu*/ void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size) { WAVEHDR* current; int remain; current = &waveBlocks[waveCurrentBlock];
45
while(size > 0) { // first make sure the header we're going to use is unprepared if(current->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR)); if(size < (int)(BLOCK_SIZE - current->dwUser)) { memcpy(current->lpData + current->dwUser, data, size); current->dwUser += size; break; } remain = BLOCK_SIZE - current->dwUser; memcpy(current->lpData + current->dwUser, data, remain); size -= remain; data += remain; current->dwBufferLength = BLOCK_SIZE; waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, current, sizeof(WAVEHDR)); EnterCriticalSection(&waveCriticalSection); waveFreeBlockCount--; LeaveCriticalSection(&waveCriticalSection);
}
// wait for a block to become free while(!waveFreeBlockCount) Sleep(10); // point to the next block waveCurrentBlock++; waveCurrentBlock %= BLOCK_COUNT; current = &waveBlocks[waveCurrentBlock]; current->dwUser = 0;
}
/*funkce slouží k alokovaní pot ebného množství místa v pam ti po íta e pro bloky zvukových dat*/ WAVEHDR* allocateBlocks(int size, int count) { unsigned char* buffer; int i; WAVEHDR* blocks; DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count; // allocate memory for the entire set in one go if((buffer = (unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, totalBufferSize)) == NULL) { //fprintf(stderr, "Memory allocation error\n"); ExitProcess(1); } // and set up the pointers to each bit blocks = (WAVEHDR*)buffer; buffer += sizeof(WAVEHDR) * count;
46
} }
for(i = 0; i < count; i++) { blocks[i].dwBufferLength = size; blocks[i].lpData = (char*)buffer; buffer += size;
return blocks;
/* funkce slouží k dealokování místa v pam ti zapln ná zvukovými daty */ void freeBlocks(WAVEHDR* blockArray) {
}
//and this is why allocateBlocks works the way it does HeapFree(GetProcessHeap(), 0, blockArray);
/*funkce je volána opera ním systémem p i vyprázdn ní bloku*/
static void CALLBACK waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { // pointer to free block counter
int* freeBlockCounter = (int*)dwInstance; //ignore calls that occur due to openining and closing the //device.
}
if(uMsg != WOM_DONE) return; EnterCriticalSection(&waveCriticalSection); (*freeBlockCounter)++; LeaveCriticalSection(&waveCriticalSection);
Následuje stru ný popis d ležitých funkcí a struktur použitých v programu a definovaných ve WIN 32 API souboru SerialPort.cpp. •
CloseHandle() - funkce uzav e handle otev eného sériového portu
•
CreaeEvent() - funkce vytvo í pojmenovaný
i nepojmenovaný
objekt událostí
47
•
CreateFile() - funkce otev e sériový port specifikovaný parametrem a vrátí handle pro p ístup k otev enému sériovému portu
•
COMMTIMEOUTS - struktura slouží k na tení a nastavení time-out parametr komunika ního za ízení. Jsou-li parametry rovny 0, pak nejsou pro operace použity
•
DCB - struktura popisující nastavení ídících parametr komunikace na sériovém portu
•
GetCommState() - funkce na te konfigura ní parametry sériového portu do struktury DCB podle aktuálního nastavení otev eného portu
•
GetLastError() - funkce zjistí hodnotu chybového kódu poslední volané procedury jednoho svázaného procesu
•
GetOverlappaedResult() - funkce zjistí stav pr b hu asynchronní operace na sériovém portu
•
OVERLAPPED
-
struktura
obsahuje
informace
použité
pi
asynchronním p ístupu k dat m sériového portu •
ReadFile() - funkce na te požadovaný po et byte ze sériového portu
•
SetCommMask() - funkce specifikuje nastavení událostí, které budou ovlada em sériového portu monitorovány
•
SetCommState() - funkce nastaví pracovní parametry sériového portu podle hodnot nastavení v ídící struktu e DCB. Funkce reinicializuje hardware v etn nastavení ovlada e, ale nevyprázdní komunika ní buffery
•
Setcommtimeouts() - funkce nastaví time-out parametry sériového portu pro veškeré operace tení a zápisu sériového portu
•
SetupComm() - funkce inicializuje parametry komunikace sériového portu
•
WaitCommEvent() - funkce
eká na výskyt specifikované události
sériového portu. U synchronního módu otev ení portu je tato funkce opušt na až po výskytu specifikované události nebo chyby. Je-li port otev en asynchronn , funkce je opušt na okamžit
a pouze
monitoruje výskyt události.
48
•
WaitforSingleObject() - funkce se vrací v okamžiku vypršení asového
limitu
nebo
v okamžiku
signalizace
události
specifikovaného objektu •
WriteFile() - funkce zapíše požadovaný po et byt
do sériového
portu
SerialPort.cpp #include "stdafx.h" #include "pcadpcm.h" #include <windows.h> #include <mmsystem.h> #include #include #include "audio.h" #include "SerialPort.h" using namespace std; /* konstruktor */ SerialPort::SerialPort() { READ_OS.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); READ_OS.Offset=0; READ_OS.OffsetHigh=0; } /* funkce uzav e handle otev eného sériového portu */ BOOL SerialPort::CloseSerial(){ CloseHandle(FHandle); return TRUE; }
/* funkce otev e sériový port specifikovaný parametrem a vrátí handle pro p ístup k otev enému sériovému portu */
void SerialPort::CreateHandle() {
FHandle = CreateFile( "COM9", GENERIC_READ | GENERIC_WRITE, // 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (FHandle == INVALID_HANDLE_VALUE){ } }
cout << "chyba neotevren seriovy port COM9"<< endl;
49
/*funkce nastavý time-out parametr komunika ního za ízení*/ void SerialPort::SetCommunicationTime(DWORD ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant, WriteTotalTimeoutMultiplier,
DWORD DWORD DWORD
DWORD WriteTotalTimeoutConstant) { COMMTIMEOUTS m_CommTimeouts; BOOL Result; m_CommTimeouts.ReadIntervalTimeout =ReadIntervalTimeout; m_CommTimeouts.ReadTotalTimeoutConstant =ReadTotalTimeoutConstant; m_CommTimeouts.ReadTotalTimeoutMultiplier =ReadTotalTimeoutMultiplier; m_CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant; m_CommTimeouts.WriteTotalTimeoutMultiplier =WriteTotalTimeoutMultiplier; Result = SetCommTimeouts (FHandle, &m_CommTimeouts); if(!Result) // RaiseCommError(sCommTimeoutsErr,GetLastError()); cout << "s casem ni neco v poradku" << endl; } /* funkce nastaví pracovní parametry sériového portu */ void SerialPort::ConfigurePort(DWORD BaudRate, BYTE ByteSize, DWORD dwParity, BYTE Parity, BYTE StopBits) { int Result ; SetupComm(FHandle,4096,4096); GetCommState(FHandle,&c); c.BaudRate=BaudRate; c.ByteSize=ByteSize; c.DCBlength=sizeof(c); c.EofChar=0; c.ErrorChar=0; c.EvtChar=0; c.fAbortOnError=FALSE; c.fBinary=TRUE; c.fDsrSensitivity=FALSE; c.fDtrControl=DTR_CONTROL_ENABLE; c.fDummy2=0; c.fErrorChar=FALSE; c.fInX=FALSE; c.fNull=FALSE; c.fOutX=FALSE; c.fOutxCtsFlow=FALSE; c.fOutxDsrFlow=FALSE; c.fParity=dwParity; // FLASE c.fRtsControl=RTS_CONTROL_HANDSHAKE; c.fTXContinueOnXoff=FALSE; c.Parity=Parity;
50
// NOPARITY c.StopBits=ONESTOPBIT; c.wReserved=0; c.wReserved1=0; c.XoffChar=0; c.XoffLim=0; c.XonChar=0; c.XonLim=0; //
Result = SetCommState(FHandle, &c); if(!SetCommState(FHandle, &c)) { cout << GetLastError() << endl; }
} /* funkce zapíše požadovaný po et byt do sériového portu*/ int SerialPort::Write(char Buf[],DWORD Count) { BOOL fWriteStat; DWORD dwBytesWritten; DWORD dwErrorFlags; DWORD dwError; DWORD dwBytesSent = 0; COMSTAT ComStat; OVERLAPPED WRITE_OS = {0}; try { fWriteStat = WriteFile(FHandle,Buf,Count,&dwBytesWritten,&WRITE_OS); if(!fWriteStat){ if(GetLastError()==ERROR_IO_INCOMPLETE){ int cekej2; cout << "cekej2" << endl; cin >> cekej2; while (!GetOverlappedResult(FHandle,&WRITE_OS,&dwBytesWritten,FALSE)){ dwError = GetLastError(); if(dwError==ERROR_IO_INCOMPLETE){ dwBytesSent +=dwBytesWritten; continue ; } ClearCommError(FHandle,&dwErrorFlags,&ComStat); break; } dwBytesSent += dwBytesWritten; } else ClearCommError(FHandle,&dwErrorFlags,&ComStat); }
else
dwBytesSent = dwBytesWritten; } catch(...){ } return dwBytesSent;
51
}
/*funkce p e te požadovaný po et byt ze sériového portu*/ int SerialPort::Read(char Buf2[],DWORD Count){ BOOL fReadStat; COMSTAT ComStat; DWORD dwErrorFlags; DWORD dwLength; DWORD dwLength2; DWORD dwBytesReceive = 0; DWORD dwError; bool WaitEventResult; DWORD FEventMask ; memset(&READ_OS,0,sizeof(READ_OS)); // READ_OS.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); WaitEventResult = WaitCommEvent(FHandle,&FEventMask,&READ_OS); cout <<"kontrolni bod read 1"<< endl; if(GetLastError()==ERROR_IO_PENDING) if (WaitForSingleObject(READ_OS.hEvent,INFINITE)==WAIT_OBJECT_0){ } else{ cout << "funkce byla prerusena"<< endl; } cout <<"kontrolni bod read 2"<< endl; try { ClearCommError(FHandle,&dwErrorFlags,&ComStat); dwLength = Count; if (dwLength>0){ fReadStat = ReadFile(FHandle,Buf2,Count,&dwLength2,&READ_OS); if(fReadStat == TRUE){ cout << READ_OS.Internal << endl; } cout << "Proveden read" << endl; if (!fReadStat){ if (GetLastError()==ERROR_IO_PENDING){ cout << "na portu nevznikla zadna operace" << endl; while(!GetOverlappedResult(FHandle,&READ_OS,&dwLength,TRUE)){ dwError = GetLastError(); if(dwError == ERROR_IO_INCOMPLETE){ dwBytesReceive += dwLength2; continue; } ClearCommError(FHandle,&dwErrorFlags,&ComStat); break; } } dwBytesReceive += dwLength2; } else
52
if(0 == ClearCommError(FHandle,&dwErrorFlags,&ComStat)){ } }
else
} catch(...) { } return dwBytesReceive; }
dwBytesReceive = dwLength2;
/*nastavení masky sériového portu*/ void SerialPort::SetSerialPort(){
SetCommMask(FHandle,EV_RXCHAR|EV_TXEMPTY|EV_ERR|EV_BREAK|EV_CT S|EV_DSR|EV_RING|EV_RLSD ); } int main(int argc, char* argv[]) { SerialPort *Serial = new SerialPort(); HWAVEOUT hWaveOut; //device handle int readBytes; short sample; char code; struct ADPCMstate state_decoder; state_decoder.previndex=0; HANDLE hFile ; //file handle WAVEFORMATEX wfx; // look this up in your documentation char buffer[1024]; // intermediate buffer for reading HANDLE hThrd; DWORD Id; waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT); waveFreeBlockCount = BLOCK_COUNT; waveCurrentBlock= 0; InitializeCriticalSection(&waveCriticalSection); /*nastaveni parametru zvuku */ wfx.nSamplesPerSec = 16000; // sample rate wfx.wBitsPerSample = 16; // sample size wfx.nChannels= 1; // channels wfx.cbSize = 0; //size of _extra_ info wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3; wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; if(waveOutOpen( &hWaveOut, WAVE_MAPPER, &wfx, (DWORD)waveOutProc, // DWORD?PTR (DWORD)&waveFreeBlockCount, // DWORD?PTR
53
CALLBACK_FUNCTION ) != MMSYSERR_NOERROR) { ExitProcess(1);
} Serial->CreateHandle(); Serial->ConfigurePort(CBR_115200,8,FALSE,NOPARITY,ONESTOPBIT); Serial->SetSerialPort(); Serial->SetCommunicationTime (1000,0,0,0,0); /*hlavní cyklus programu*/ while(1) { Serial->Read((char*)buffer,sizeof(buffer)); /*ctení ze sériové linky*/ for(int i = 0;i<1024;i++){ code = buffer[i]; sample = (short)ADPCMDecoder((code>>4)&0x0f,&state_decoder); /*dekomprimace*/ /*p ehrání*/ writeAudio(hWaveOut, (char *)&sample, sizeof(short)); sample = (short)ADPCMDecoder((code)&0x0f,&state_decoder); writeAudio(hWaveOut, (char *)&sample, sizeof(short)); } } /*deincializace*/ while(waveFreeBlockCount < BLOCK_COUNT) Sleep(10); // unprepare any blocks that are still prepared for(int i = 0; i < waveFreeBlockCount; i++)
}
if(waveBlocks[i].dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR)); DeleteCriticalSection(&waveCriticalSection); freeBlocks(waveBlocks); waveOutClose(hWaveOut); WaitForSingleObject ( hThrd , INFINITE ); CloseHandle ( hThrd ); Serial->CloseSerial(); delete Serial; cin.get() ; return 0;
54
B.2 Program pro procesor dsPIC30F4013 Main.cpp #include #include #include <math.h> #include #include <stdio.h> #include "pcadpcm.h" _FOSC(CSW_FSCM_OFF & XT_PLL16); _FWDT(WDT_OFF); //Turn off the Watch-Dog Timer. _FBORPOR(MCLR_EN & PWRT_OFF); //Enable MCLR reset pin and turn off the //power-up timers. _FGS(CODE_PROT_OFF); //Disable Code Protection int audioData[32]; int main (void) { int i, j; int full = 0; int buffer[4]; int horniB; int dolniB; char horniBChar; #define true 1 #define false 0 char horni = true; char dolni = false; char send = false; char code2; int sample; char code; struct ADPCMstate state_coder; ADPCFG = 0xFFFF; TRISB = 0xFFFC; initCodec(); CloseDCI(); /* Configure DCI receive / transmit interrupt */ ConfigIntDCI(DCI_INT_OFF); OpenDCI( /* funkce nakonfiguruje DCI*/ DCI_EN & DCI_IDLE_CON & DCI_DIGI_LPBACK_DIS & DCI_SCKD_INP & DCI_SAMP_CLK_RIS & DCI_FSD_OUP &
55
DCI_TX_ZERO_UNF & DCI_SDO_ZERO & DCI_DJST_OFF & DCI_FSM_I2S, DCI_BUFF_LEN_4 & DCI_FRAME_LEN_1 & DCI_DATA_WORD_16, 0, DCI_EN_SLOT_ALL, DCI_EN_SLOT_ALL); /* funkce nakonfiguruje UART */ OpenUART1( UART_EN & UART_IDLE_STOP & UART_ALTRX_ALTTX & UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_DIS_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT,
);
UART_INT_TX & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR, 7
while (1) { if (DataRdyDCI()) { if (full) { LATB |= 0b01; } else { for(i = 0; i < 4; i++) { buffer[i] = ReadDCI(i);/*nacteni audio dat*/ } if(send == false){ /*komprimace*/ code = ADPCMEncoder(buffer[0],&state_coder); code = (code << 4) & 0xf0; code2 = ADPCMEncoder(buffer[2],&state_coder); code = code | code2 ; send = true; }
/*funkce vrací status o tom jeli UART zaneprázdn n. Je-li zaneprázdn n vrací hodnotu 1*/ if(!BusyUART1() && send){
56
}
}
} full = 1;
LATB |= 0b01; WriteUART1(code); send = false;
if (BufferEmptyDCI()) { if (full) { for(i = 0; i < 4; i++) { WriteDCI(buffer[i], i); } full = 0; } } if (isAdcOverloaded()) { LATB |= 0b10; } else { LATB &= ~0b10; }
}
} return(0);
57
C. Obsah p iloženého CD \SRC \DSPIC - zdrojové kódy pro procesor dsPIC30F4013 \APLIKACE - zdrojové kódy aplikace \MSVAD - zdrojové kódy MSVAD \DOKUMENTY – elektronická podoba této práce
58