Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2015:sstv-gen

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2015:sstv-gen [2016/01/26 04:44]
Tomáš Kret [Firmware]
2015:sstv-gen [2016/01/26 18:04] (aktuální)
Tomáš Kret [Záver]
Řádek 1: Řádek 1:
 ====== Generátor SSTV signálu ====== ====== Generátor SSTV signálu ======
 +     * Tomáš Kret
 +     * xkrett00@stud.feec.vutbr.cz
 ===== Zadanie ===== ===== Zadanie =====
 Implementujte audio generátor pre signál SSTV (slow-scan television),​ napr. mód Martin M1 alebo Robot B&W. Obrazové data prečítajte z SD karty alebo USB flash disku, signál vygenerujte a odošlite pomocou DAC alebo zvukového kodeku. Overte príjem softwarom MMSSTV. Implementujte audio generátor pre signál SSTV (slow-scan television),​ napr. mód Martin M1 alebo Robot B&W. Obrazové data prečítajte z SD karty alebo USB flash disku, signál vygenerujte a odošlite pomocou DAC alebo zvukového kodeku. Overte príjem softwarom MMSSTV.
Řádek 34: Řádek 36:
   - 3x I<​sup>​2</​sup>​c   - 3x I<​sup>​2</​sup>​c
 ===== Firmware ===== ===== Firmware =====
-O generovanie zvuku sa stará audio kodek, do ktorého prúdi DMA stream, kde sa využíva headphone výstup. Harmonický signál je vytváraný pomocou funkcie //​arm_sin_f32()//​ podporovanej floatovacou jednotkou. Aby sa dosiahla vyššia účinnosť prenosu, je mono signál prerozdelený pre ľavý a pravý kanál.+Vytváraný bol pomocou STM32CubeMX 4.12 v prostredí Em:Bitz 0.42 a pomocou ďalších podporných knižníc. ​O generovanie zvuku sa stará audio kodek, do ktorého prúdi DMA stream, kde sa využíva headphone výstup. Harmonický signál je vytváraný pomocou funkcie //​arm_sin_f32()//​ podporovanej floatovacou jednotkou. Aby sa dosiahla vyššia účinnosť prenosu, je mono signál prerozdelený pre ľavý a pravý kanál.
  
 **Vývojový diagram:** **Vývojový diagram:**
Řádek 58: Řádek 60:
 </​code>​ </​code>​
  
 +**Významné funkcie v súboru main.c**
  
 +Vo firmware sa používajú 3 druhy bufferov:
 +<​code>​
 +/* USER CODE BEGIN 0 */
 +static int8_t pol2 = 0;
 +static int8_t pol1 = 0;
 +static int16_t wind[2*BUFFER_SIZE] = {0};
 +static int16_t buffer[4*BUFFER_SIZE] = {0};
 +static uint8_t RGB[4*BUFFER_SIZE] = {0};
 +</​code>​
 +Buffer wind sa odosiela priamo do dma streamu, obsahuje ľavý a pravý kanál okopírovaného z mono signálu. Buffer buffer obsahuje vzorky harmonického signálu, ktorý je vzorkovaný 48000 Hz. RGB obsahuje hodnoty jednolivých pixelov načítaných z USB flash. BUFER_SIZE je stanovené na 4096, čo je hodnota 2<​sup>​n</​sup>,​ vďaka čomu je možné realizovať kruhový buffer pomocou logického súčinu &​(BUFFER_SIZE-1).
 +
 +Úryvok časti main:
 +<​code>​
 + /* USER CODE BEGIN 2 */
 +   ​BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO,​ 70, 48000);
 +
 +  /* USER CODE END 2 */
 +
 +  /* Infinite loop */
 +  /* USER CODE BEGIN WHILE */
 +    while (1)
 +    {
 +  /* USER CODE END WHILE */
 +        MX_USB_HOST_Process();​
 +  /* USER CODE BEGIN 3 */
 +        if( f_mount( &​fatfs,"",​0) != FR_OK )
 +        {
 +            while(1);
 +        }
 +        if(HAL_GPIO_ReadPin(GPIOA,​ GPIO_PIN_0) == 1)
 +        {
 +            BSP_AUDIO_OUT_Play((uint16_t*)wind,​ BUFFER_SIZE*2);​
 +            BSP_LED_On(LED4);​
 +            sstv_send();​
 +        }
 +        HAL_Delay(50);​
 +    }
 +  /* USER CODE END 3 */
 +</​code>​
 +
 +DMA prenos sa v počiatočných podmienkach začne pri prázdnych bufferoch, o naplnení vzorkami sa starajú až funkcie volané funkciou //​sstv_send()//​. Funkcia //​f_mount()//​ priraďuje tabuľkový systém pre knižnicu FATFS. //​MX_USB_HOST_Process()//​ obsaluhuje USB zbernicu pre enumeráciu,​ nastavuje stavový automat USB zbernice a pod.
 +
 +Funkcia //​sstv_send()//:​
 +<​code>​
 +void sstv_send(void) {
 +    int32_t ln = 0, uk = 0;
 +    BSP_LED_Off(LED6);​
 +    sstv_init();​
 +    if(f_open(&​fp,​name,​FA_READ)!=FR_OK)
 +    {
 +        while(1);
 +    }/*red data from flash*/
 +    for (int32_t i=0; i<256; i++){
 +        if (!(i&​16)) {
 +            f_lseek(&​fp,​ i*960+ln);
 +            if(f_read(&​fp,​RGB,​4*BUFFER_SIZE,&​ret)!=FR_OK)
 +            {
 +                while(1);
 +            }
 +            uk=0;
 +        }
 +
 +        frgen(1200,​4842);​
 +        ln = 0;
 +        while (ln<960) {
 +            frgen(1500+(RGB[uk])*3.137254902,​458);​
 +            if (ln%960==320 || ln%960==640) frgen(1500,​750);​
 +            uk++;
 +            ln++;
 +        }
 +    }
 +    f_close(&​fp);​
 +    BSP_LED_On(LED6);​
 +}
 +</​code>​
 +Vo funkcii //​sstv_send()//​ sa rieši odoslanie VIS kódu pomocou funkcie //​sstv_init()//,​ načítanie ďalších pixelov z USB (funkciou //​f_read()//​) posúvaním pointera na súbor uložený vo flash disku (funkciou //​f_lseek()//​),​ generovanie synchronizačných signálov:
 +  -//​frgen(1200,​4842);//​ -začiatok nového riadku
 +  -//if (ln%960==320 || ln%960==640) frgen(1500,​750);//​ -oddeľovač farieb
 +  -//​frgen(1500+(RGB[uk])*3.137254902,​458);//​ -modulovanie samotných pixelov
 +Keďže diskrétny signál s periódou vzorkovania 20.83 us neumožňoval nastaviť dobrú synchronizáciu,​ bolo potrebné upraviť pôvodné hodnoty synchronizačných signálov (miesto 572 ms na 750 ms a miesto 4,862 ms na 4,842 ms).
 +
 +Funkcia generujúca Vis code pre Martin M1:
 +<​code>​
 +void sstv_init(void) {
 +    frgen(1200,​3000000); ​   //3s test frequency 1200 Hz
 +    frgen(1900,​300000);​
 +    frgen(1200,​10000);​
 +    frgen(1900,​300000);​
 +
 +    frgen(1200,​30000); ​ //start bit
 +    frgen(1300,​30000);​
 +
 +    frgen(1300,​30000);​
 +    frgen(1100,​30000);​
 +    frgen(1100,​30000);​
 +
 +    frgen(1300,​30000);​
 +    frgen(1100,​30000);​
 +    frgen(1300,​30000);​
 +    frgen(1100,​30000);​
 +    frgen(1200,​30000); ​ //stop bit
 +
 +}
 +</​code>​
 +
 +Funkcia generujúca harmonický signál vzorkovaný 48k:
 +<​code>​
 +void frgen(int32_t frq, int32_t tm) {
 +    /*freq[Hz] tm[us]*/
 +    static int64_t ph = 0;
 +    static int32_t ind1=0;
 +    int32_t ind2=0;
 +    int32_t tmd = 0;
 +    float32_t tmdel = tmd*(20.833333333);​
 +    while((tmdel<​=tm)) {
 +        float32_t x=2.0*3.141592*(frq*ind2+ph)*0.000020833333333;​
 +        float32_t y=32767.0;
 +        buffer[ind1] = (int16_t)(arm_sin_f32(x)*y);​
 +        ind1++;
 +        ind2++;
 +        tmd++;
 +        if (ind1 >= BUFFER_SIZE*4) {
 +            //​ind1&​=(BUFFER_SIZE*4-1);​
 +            ind1 = 0;
 +            BSP_LED_On(LED5);​
 +            while(!pol2);​
 +            pol2=0;
 +            BSP_LED_Off(LED5);​
 +        }
 +        else if (ind1 == (BUFFER_SIZE*2)) {
 +            BSP_LED_On(LED3);​
 +            while(!pol1);​
 +        BSP_LED_Off(LED3);​
 +        pol1=0;
 +        }
 +        tmdel = tmd*(20.833333333);​
 +    }
 +    ph += frq*ind2;
 +}
 +</​code>​
 +Funkcia //​frgen(int32_t frq, int32_t tm)// je základná funkcia využívaná generátorom. Generuje harmonický signál s nastaviteľnou frekvenciou a časom dĺžky trvania. Pre SSTV prenos je potrebné zabezpečiť plynulú zmenu kmitočtu - o to sa stará pričítavanie zvyškovej fázy do 64-bitovej premennej ph, ktorá je daná súčinom diskrétneho času s frekvenciou. Premenné typu float32_t alokujú miesto pre float unit a tým úrychľujú výpočet. Buffer pre výpočet vzoriek je rozdelený do dvoch častí pomocou premenných pol 1 a pol2. Kým prebieha výpočet v 1. častu, DMA prenos prebieha v druhej časti a naopak. Buffere sú kruhové. Premenná tmdel sleduje dĺžku generovaného signálu.
 +
 +Obsluha prerušenia na koniec DMA prenosu:
 +<​code>​
 +void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
 +{
 +  static int32_t index = 0;
 +  if(0)
 +  {
 +      BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW);​
 +      index = 0;
 +  }
 +  else
 +  {
 +      static uint8_t ind = 0;
 +      BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&​wind[0],​ 2*BUFFER_SIZE);​
 +
 +      index = index + BUFFER_SIZE;​
 +      index &= (BUFFER_SIZE*4-1);​
 +      if (index>​=BUFFER_SIZE*2) {
 +              pol2 = 1;
 +              pol1=0;
 +              BSP_LED_Off(LED5);​
 +      }
 +      else {
 +            pol1=1;
 +            pol2=0;
 +            BSP_LED_Off(LED3);​
 +      }
 +
 +
 +      pref(index);​
 +
 +  }
 +
 +}
 +</​code> ​
 +Wind je kruhový bufer, do ktorého sa nové hodnoty vkladajú až zavolaním funkcie //​pref(int32_t indx)//:
 +<​code>​
 +void pref(int32_t indx) {
 +    int ind = 0;
 +    do {
 +        wind[(ind*2)&​(BUFFER_SIZE*2-1)] = buffer[(ind+indx)&​(4*BUFFER_SIZE-1)];​
 +        wind[(ind*2+1)&​(BUFFER_SIZE*2-1)] = buffer[(ind+indx)&​(4*BUFFER_SIZE-1)];​
 +        if ((ind+indx)>​(4*BUFFER_SIZE-1)) BSP_LED_Off(LED4);​
 +        else if ((ind+indx)<​(2*BUFFER_SIZE-1)) BSP_LED_On(LED4);​
 +        ind++;
 +
 +    } while ((ind*2+1)<​=(2*BUFFER_SIZE+buf));​
 +
 +}
 +</​code>​
 +Funkcia //​pref(int32_t indx)// slúži na duplikovanie vzoriek do oboch kanálov. Hodnoty bufferov sa načítavajú a zapisuju cyklicky, čím sa predpočítajú prvky do ďalšieho kroku. ​
 +
 +Celý firmware pre EmBitz {{:​2015:​sstv-gen:​sstv.zip|tu}}.
 +
 +Súbory uložené na USB flash disku {{:​2015:​sstv-gen:​matlab_generated_files.zip|tu}}.
 +
 +===== Overenie funkčnosti =====
 +{{ :​2015:​sstv-gen:​img_20160126_062859_1.jpg?​300 |}}
 +                                              Testovacie podmienky
 +{{ :​2015:​sstv-gen:​test.png |}}
 +{{ :​2015:​sstv-gen:​test_lines.jpg |}}
 +{{ :​2015:​sstv-gen:​landscape.jpg |}}
 +{{ :​2015:​sstv-gen:​sstv.jpg |}}
 +                     ​Výsledky prenosov (vpravo synchronizačné signály) a porovnanie s originálmi
 +**Videozáznam prenosu SSTV**
 +{{youtube>​sZ8ZAE_yu98?​medium}}
 +===== Záver =====
 +Na obrázkoch je vidieť, že dochádza k miernemu rozladeniu farieb ako aj synchronizácie,​ rozladenie môže byť spôsobené vlastnosťami mikrofónu. Synchronizácia by sa mohla zlepšiť pridaním multitaskingu,​ odstránením blokujúcich čakaní, lepšou synchronizáciou jednotlivých buferov, zvýšením vzorkovacieho kmitočtu a lepším zaokrúhľovaním času. Pre správne načítanie dát z usb po zapnutí treba  približne 5 až 10 sekúnd čakať pred stlačením user tlačidla kvôli dokončeniu enumerácie,​ avšak nie je to nikde signálizované,​ čo je tiež potrebné vyriešiť.  ​
2015/sstv-gen.1453779898.txt.gz · Poslední úprava: 2016/01/26 04:44 autor: Tomáš Kret