Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| Následující verze | Předchozí verze | ||
|
2015:audio-interface [2016/01/17 19:51] Martin Kokolia vytvořeno |
2015:audio-interface [2016/01/17 22:13] (aktuální) Martin Kokolia [Závěr] |
||
|---|---|---|---|
| Řádek 14: | Řádek 14: | ||
| STM32F4 Discovery | STM32F4 Discovery | ||
| - | + | {{:2015:cm4-math:stm32f4_discovery_board.jpg?300|}} | |
| Key Features | Key Features | ||
| Řádek 41: | Řádek 40: | ||
| ====== Software ====== | ====== Software ====== | ||
| - | Základní knihovny pro obsluhu desky a periferií jsou vygenerovány pomocí STM32CubeMX. Zde bylo zvoleno připojení přes FS USH jako Audio device. Obsluha přes I2C1 a data jsou přenášena pomocí I2S2 v polovičním duplexním režimu. Dále jsou použity ADC 1 a 2 a hadrwarové tlačítko. | + | Základní knihovny pro obsluhu desky a periferií jsou vygenerovány pomocí STM32CubeMX. Zde bylo zvoleno připojení přes FullSpeed USB jako Audio device. Obsluha příkazy pro audio přenos přes I2C1 a data jsou přenášena pomocí I2S2 v polovičním duplexním režimu. Dále jsou použity ADC 1 a 2 a hadrwarové tlačítko. |
| + | |||
| + | |||
| V hlavním souboru main.c probíha inicializace ADC převodníku, USB device audio class a audio kodeku pro přehrávání audio výstupu. | V hlavním souboru main.c probíha inicializace ADC převodníku, USB device audio class a audio kodeku pro přehrávání audio výstupu. | ||
| Řádek 47: | Řádek 49: | ||
| Použité knihovny v soubotu main.c | Použité knihovny v soubotu main.c | ||
| + | <code c> | ||
| + | #include "stm32f4xx_hal.h" | ||
| + | #include "usb_device.h" | ||
| + | #include "stm32f4xx_hal_adc.h" | ||
| + | #include "cs43l22.h" | ||
| + | #include "stm32f4_discovery_audio.h" | ||
| + | </code> | ||
| - | * #include "stm32f4xx_hal.h" | + | <code c> |
| - | * #include "usb_device.h" | + | |
| - | * #include "stm32f4xx_hal_adc.h" | + | |
| - | * #include "cs43l22.h" | + | |
| - | * #include "stm32f4_discovery_audio.h" | + | |
| - | + | ||
| - | <code> | + | |
| assert_param(IS_ADC_CHANNEL(sConfig->ADC_CHANNEL_1)); | assert_param(IS_ADC_CHANNEL(sConfig->ADC_CHANNEL_1)); | ||
| | | ||
| Řádek 63: | Řádek 66: | ||
| void ADC_Init(hadc); | void ADC_Init(hadc); | ||
| | | ||
| - | cs43l22_Init(29, OUTPUT_DEVICE_SPEAKER, 60, AUDIO_FREQUENCY_48K); | + | cs43l22_Init(DAC_CHANNEL_1, OUTPUT_DEVICE_SPEAKER, 60, AUDIO_FREQUENCY_48K); |
| + | |||
| + | cmd = AUDIO_CMD_START; | ||
| + | </code> | ||
| + | |||
| + | <code c> | ||
| + | while (1) | ||
| + | { | ||
| + | if (channel==1) | ||
| + | {assert_param(IS_ADC_CHANNEL(sConfig->ADC_CHANNEL_1)); | ||
| + | channel=0; | ||
| + | } | ||
| + | else | ||
| + | {assert_param(IS_ADC_CHANNEL(sConfig->ADC_CHANNEL_2)); | ||
| + | channel=1; | ||
| + | } | ||
| + | /* USER CODE END WHILE */ | ||
| + | |||
| + | |||
| + | /* USER CODE BEGIN 3 */ | ||
| + | |||
| + | } | ||
| </code> | </code> | ||
| Nejprve je inicializován AD převodník a přiřazeným kanálem číslo jedna, který odpovídá převodníku ADC1. Na tento převodník je přivedeno napětí z potenciometru, který ovládá Volume přehrávání audio výstupu. Následně jsou přiřazeny patřičné parametry a vzorkovací frekvence. | Nejprve je inicializován AD převodník a přiřazeným kanálem číslo jedna, který odpovídá převodníku ADC1. Na tento převodník je přivedeno napětí z potenciometru, který ovládá Volume přehrávání audio výstupu. Následně jsou přiřazeny patřičné parametry a vzorkovací frekvence. | ||
| - | Dále je inicializován audio kodek, kde je přižen výstupní pin na Jack 3.5 mm, zvolen typ výstupního zařízení, počáteční hlasitost v procentech a vrozkovací frekvence na 48 kHz. Stejná je vzorkovací frekvence AD převodníku a rychlost přenosu po USB. | + | Dále je inicializován audio kodek, kde je přiřazen výstupní pin na Jack 3.5 mm, zvolen typ výstupního zařízení, počáteční hlasitost v procentech a vrozkovací frekvence na 48 kHz. Stejná je vzorkovací frekvence AD převodníku a rychlost přenosu po USB. |
| - | Hlavní část programu se provádí v souboru usbd_audio_if.c, která využívá další knihovny | + | Ve smyčče While je přepínán vstup mezi AD převodníky 1 a 2, takže je střídavě přijímán audio signál a snímáno nastavení Volume. |
| - | * #include "usbd_audio_if.h" | ||
| - | * #include "stm32f4xx_hal_adc.h" | ||
| - | * #include "usbd_audio.h" | ||
| - | * #include "stm32f4_discovery_audio.h | ||
| - | Veškeré procesy se provádí při volání funkce AUDIO_AudioCmd_FS. K jejímu volání dochází při naplnění audio bufferu. | ||
| - | Je využito proměnných z knihoven | + | |
| - | <code> | + | |
| + | Hlavní část programu se provádí v souboru usbd_audio_if.c, která využívá další knihovny | ||
| + | |||
| + | <code c> | ||
| + | #include "usbd_audio_if.h" | ||
| + | #include "stm32f4xx_hal_adc.h" | ||
| + | #include "usbd_audio.h" | ||
| + | #include "stm32f4_discovery_audio.h | ||
| + | </code> | ||
| + | |||
| + | Veškeré procesy se provádí při volání funkce AUDIO_AudioCmd_FS. K jejímu volání dochází při naplnění audio bufferu ''pbuf''. | ||
| + | |||
| + | Je využito proměnných ze souboru main.c | ||
| + | <code c> | ||
| extern hadc; | extern hadc; | ||
| - | extern USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]; | + | extern channel; |
| + | extern cmd; | ||
| </code> | </code> | ||
| - | <code> | + | <code c> |
| static int8_t AUDIO_AudioCmd_FS (uint8_t* pbuf, uint32_t size, uint8_t cmd) | static int8_t AUDIO_AudioCmd_FS (uint8_t* pbuf, uint32_t size, uint8_t cmd) | ||
| { /* USER CODE BEGIN 2 */ | { /* USER CODE BEGIN 2 */ | ||
| Řádek 94: | Řádek 127: | ||
| if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_0)==GPIO_PIN_RESET) | if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_0)==GPIO_PIN_RESET) | ||
| - | BSP_AUDIO_OUT_Play(pbuf, 16); | + | {BSP_AUDIO_OUT_Play(pbuf, 16); |
| + | cmd = AUDIO_CMD_PLAY; | ||
| + | } | ||
| break; | break; | ||
| case AUDIO_CMD_PLAY: | case AUDIO_CMD_PLAY: | ||
| - | pbuf = USBD_AUDIO_DataIn(USB_LEN_DEV_QUALIFIER_DESC,AUDIO_OUT_EP); | + | |
| if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_0)==GPIO_PIN_RESET) | if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_0)==GPIO_PIN_RESET) | ||
| { | { | ||
| Řádek 116: | Řádek 150: | ||
| break; | break; | ||
| - | vol = 100 * 0xFF / HAL_ADC_GetValue(hadc); | + | if (channel=0) |
| + | vol = 100 * 0xFF / HAL_ADC_GetValue(hadc); | ||
| + | else | ||
| + | in = HAL_ADC_GetValue(hadc); | ||
| + | |||
| + | USBD_AUDIO_DataOut(DEVICE_FS,AUDIO_OUT_EP); | ||
| BSP_AUDIO_OUT_SetVolume(vol); | BSP_AUDIO_OUT_SetVolume(vol); | ||
| + | pbuf = USBD_AUDIO_DataIn(DEVICE_FS,AUDIO_OUT_EP); | ||
| + | cs43l22_Play(DAC1_CHANNEL_1, pbuf,8); | ||
| } | } | ||
| return (USBD_OK); | return (USBD_OK); | ||
| Řádek 137: | Řádek 179: | ||
| </code> | </code> | ||
| + | Vstupními parametry funkce jsou označení audio bufferu, jeho velikost a příkaz pro audio zařízení ''cmd''. Nejprve je zařízení v ražimu Start, kde dojde k inicializaci všech periferií atd. Po stistku hardwarového tlačítka přechází do ražimu Play. | ||
| + | Když je zařízení v ražimu Play, pak při stisku tlačítka dochází k přepínácí režimu Mute. | ||
| + | Dále dojde k čtení hodnoty z AD převodníku pro zvolení hlasitosti přehrávání, respektive načtení audio vstupu druhého AD převodníku a nakonec jsou data ze vstupního bufferu s daty přijatých po USB přenesen do výstupního bufferu audio výstupu. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | {{:2015:bez_nazvu.png?300|}} | ||
| + | |||
| + | Správce zařízení | ||
| + | ---- | ||
| + | |||
| + | {{:2015:bez_nazvu2.png?300|}} | ||
| + | |||
| + | Zařízení pro přehrávání | ||
| + | ---- | ||
| + | |||
| + | |||
| + | ====== Závěr ====== | ||
| + | |||
| + | Ze screenshotů je patrné že zařízení se po připojení k PC přihlásí jako audio zařízení pro přehrávání a je připraveno k přenosu dat. Kvůli střídavému čtení hodnot z AD převodníku 1 a 2 může docházet ke ztrátám některých vzorků, pokud by přepínání mezi čtením z převodníků probíhalo pomaleji než s frekvencí 48 kHz. | ||
| + | |||
| + | Bohužel při testech nebylo dosaženo požadované funkčnosti, což je zřejmě způsobeno špatnými parametry pro funkce obsluhující USB přenos. Program přechízi do režimu Play a funguje i Mute a Volume, ale do bufferu se nejspíše nedostávájí správná data. Dokumentace výrobce je absolutně nepřehledná a postrádá faktické informace o skutečném významu a formátu parametrů, takže notná část parametrů funkcí byla odhadnuta podle obsahu knihoven. | ||