Skocz do zawartości

Sipeed Tang Nano 4k z ADC - Gowin FPGA Designer


Gieneq

Pomocna odpowiedź

11 minut temu, slon napisał:

Zapytam tak z ciekawości: jak ma się ta płytka (do końca miesiąca jest promocja) do Tang Nano 4k? Puki co ceny mają zbliżone.

Cześć,

"CmodS6" to płytka z FPGA Spartan6 (czyli jedne generacja do tyłu w stosunku do najnowszej 7). Ta konkretna wersja układu FPGA Spartan6 ma małą ilość zasobów (LUT i FF oraz DSP). Soft do syntezy to Xilinx "ISE", czyli też nie najnowszy (Vivado). Główna różnica to fakt iż płytka ze Spartanem6 nie zawiera hard procesora (Tang Nano 4K ma processor ARM Cortex-M). Płytka Tang Nano 4K ma także całkiem sporą pamięć RAM (mówimy o zewnętrznej pamięći RAM, nie Block-RAM w układzie FPGA), oraz dedykowany interfejs do kamery (którego CModS6 nie posiada).

Podsumowując płytka "Tang Nano 4K" jest bardziej zaawansowana i ma więcej zasobów (także podstawowych LUT i FF). Płytka CmodS6 jest znanego producenta i znajdziesz do niej więcej materiałów w sieci. Jeśli miałbym wybrać płytkę pod jakiś projekt to wybrałbym "Tang nano 4K". Jeśli byłbym początkującym w układach programowalnych i chciałbym się na danym zestawie FPGA ich uczyć to wybrałbym "CmodS6".

Pozdrawiam

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Przed chwilą, Elvis napisał:

Warto też wspomnieć, że płytka CmodS6 nie jest już produkowana, więc ta promocja to wietrzenie magazynów… 

nie jestem też pewien, czy cmods6 ma wbudowany programator / jtag.

Cześć,

CmodS6 używa programu "Adept" firmy Digilent do programowania. Niestety nie używałem nigdy tego oprogramowania, więc się nie wypowiem jak działa.

Pozdrawiam

 

 

Link do komentarza
Share on other sites

Skasowałem mój komentarz odnośnie programatora, bo na szybko przeczytałem, że coś jest. Ale jeśli to jakiś dedykowany wynalazek to lepiej uważać, wsparcie dla nowych systemów jak win11 pewnie będzie problemem.

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Cześć @FlyingDutch też na razie odłożyłem programowanie, mam zamówiony ESP32-D4, mam nadzieję że rozwiąże to niektóre problemy. W międzyczasie odpiłem kod na STM32 i działał całkiem dobrze.

Kilka ostatni dni spędziłem na douczaniu się elektroniki analogowej, widzę że mam tu spore braki. Wiem że jeżeli rozwiązanie działa to znaczy że jest dobre, ale chciałbym móc powiedzieć nieco więcej dlaczego użyłem dany element i nie snuć domysłów. Jak skończę schemat to wrócę do tematu. Założyłem gałąź projektu, w folderze ze schematem wrzucam aktualizacje: https://github.com/Gieneq/Audio-Spectrum-Display/tree/Slight_refactor/schematics

Edytowano przez Gieneq
  • Lubię! 1
Link do komentarza
Share on other sites

Cześć,

ponieważ do pracy z modułami przetworników ADC często  jest potrzebny zewnętrzny sygnał zegarowy, postanowiłem poszukać modułu zegara z pętlą PLL. Oczywiście taki sygnał można wygenerować korzystając z płytki FPGA lub mikro-kontrolera (dla większych częstotliwości jest to problem), jednak stwierdziłem, że przydałby się nieduży (i niedrogi) uniwersalny moduł zegarowy. Ku mojemu zaskoczeniu udało mi się znaleźć taki moduł w naprawdę niezłej cenie na Aliexpress.com - tutaj link do układu:

https://www.aliexpress.com/item/4000040035169.html?spm=a2g0o.productlist.0.0.d553258aWqW0NU&algo_pvid=f667ae59-11f9-43be-a5d5-5226b18a1066&algo_exp_id=f667ae59-11f9-43be-a5d5-5226b18a1066-0&pdp_ext_f={"sku_id"%3A"10000000089139125"}&pdp_npi=1%40dis|PLN||16.6|||||%400b0a119a16513369436153906ea97b|10000000089139125|sea

 Cena około 21 PLN z wysyłką. Generowane trzy niezależne zegary (sensowne gniazda wyjściowe). Zakres częstotliwości zegara: od 8 KHz do 160 MHz. Oparte na IC si5351 - programowane przez I2C (potrzebne jakieś małe Arduino).

Znalazłem nawet kod do Arduino dla tego układu - patrz artykuł:

https://learn.adafruit.com/adafruit-si5351-clock-generator-breakout/wiring-and-test

A tutaj link do datasheet'a dla układu si5351:

https://cdn-shop.adafruit.com/datasheets/Si5351.pdf

Hej @Gieneq może tobie też się przyda do generacji zegara dla układów przetworników ADC 🙂

Ja już zamówiłem dwie sztuki.

Pozdrawiam

Link do komentarza
Share on other sites

Cześć @FlyingDutch 

Wygląda ciekawie, mam tylko nadzieję że będzie działać. Mam coraz większe uprzedzenia do układów z ALi zwłaszcza w obecnej sytuacji braków wszystkiego 😕 

Też działam z tematem, ale średnio mi idzie. Zastanowiłem się ostatnio nad jakimś celem, który pozwoli mieć realny efekt w tym projekcie i który uda mi się wrzucić np. na YT i wymyśliłem, że na pewno chcę ADS1256 i WiFi. Wiec biorę na główny mikrokonroler STM32 a do WiFi ESP32 C3 - może udałoby się na samym ESP, no trudno, będzie więcej zasobów. Dlatego już bez dziesiątek eksperymentów usiadłem do zaprogramowania STMa. Po dłuższym czasie walki z brakiem odpowiedzi od ADS1256 dla pewności jeszcze raz podłączyłem UNO - działa. W końcu się udało, cykliczne odczyty śmigają, ale wymarzyłem sobie odczyt od przerwania na pinie DDRY i tu coś się dzieje dziwnego.

image.thumb.png.d91f9c034950556a810da7466b716fca.png

Na dole jest DDRY, na górze CS. W samym przerwaniu pomimo ułożenia priorytetów nie udało mi się dać blokującego odczytu SPI, jeszcze niewiem dlaczego

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == ADS_DDRY_Pin) {
	  read_flag = 1;
  }
}

i w mainie:

  while (1)
  {
	  if(read_flag){
		  read_flag = 0;
//		  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
//		  delay_us(1);
		  reading = ADS_readCurrentChannel();
	  }

10 us przeskoku to bardzo dużo, jakieś dziwne. Ale najdziwniejsza jest ta dziura w zegarze, która przynajmniej nie wynika z funkcji:

uint32_t ADS_read_uint24() {
  uint8_t inbuff[3] = {0,0,0};
  uint32_t value;
  HAL_SPI_Receive(&hspi2, inbuff, 3, HAL_MAX_DELAY);
  value = ((long)inbuff[0] << 16) + ((long)inbuff[1] << 8) + ((long)inbuff[2]);
  return value;
}

Myślałem, że może analizator szwankuje ale na oscyloskopie widać to samo, a nawet sytuacja jest bardziej chaotyczna:

image.thumb.png.97a4a655e4c51c5ee94d8eb1f2c3dfa4.pngimage.thumb.png.1d7786aff55b77bc6bf7503a2103d15b.png

Sygnał DDRY występuje w równych odstępach ale jego wypełnienie jest podejrzanie nierówne.

Na razie cieszę się, że pomimo utrudnień da się odczytać pomiary, ale muszę to jeszcze dopracować.

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

@Gieneq Pierwsze pytanie - jakich opcji optymalizatora używasz. A ogólnie to chyba lepiej użyć DMA, a do wyzwalania odczytu zamiast przerwania zdarzeń - obsługa przerwania też zajmuje czas.

Edit: z tych zdarzeń chyba muszę się wycofać 😞 Chyba nie da się tego zrobić, a szkoda, bo dla wbudowanego ADC jest to chyba najlepsza metoda na odczytywanie danych w precyzyjnie określonych odstępach czasu.

Edit2: jednak za szybko napisałem - wszystko się da, a nawet jeśli pozornie nie, to jest na to obejście. Można przykładowo skonfigurować timer, żeby generował zdarzenie po zmianie pinu DDRY, a wtedy DMA może już spokojnie wykonać transfer poprzez SPI. W każdym razie zrobienie takiej transmisji bez udziału procesora to ciekawe ćwiczenie 🙂

Edytowano przez Elvis
  • Lubię! 2
Link do komentarza
Share on other sites

(edytowany)

Dzięki @Elvis DMA pomogło, tylko wyszedł błąd kolejności inicjalizacji w Cubie: https://electronics.stackexchange.com/questions/537219/stm32f7-hal-spi-dma-tx-does-not-work

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();
  MX_DMA_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */

Po wrzuceniu  MX_DMA_Init(); wyżej zaczęło działać:

image.thumb.png.243ed0a03efc881c615a5a11922f0689.png

image.thumb.png.c4aae47ec01e70344a973be52d1f5fc5.png

image.thumb.png.bf7277ea031bb29eeb8ed72825a47053.png

I nawet udało się odczytać. Dodałem jeszcze sprzętowy NSS ale nie było wielkiej poprawy.

image.thumb.png.b117e705f70f062c152259028e89ae5f.png

Jeszcze upewniłem się że rozumiem jak działa tryb ciągły. W sumie wygląa na to, że gdyby po czasie 

image.thumb.png.e7cd275ecaf18ceafcb4966efb33b3ce.png

Nie ma jakiś specjalnych wymagań czasowych, a CS może być zwarty z masą:

image.thumb.png.87d3ee5e7ad6e7958e6edde5d9bc7640.png

 

Dnia 2.05.2022 o 16:15, Elvis napisał:

Można przykładowo skonfigurować timer, żeby generował zdarzenie po zmianie pinu DDRY, a wtedy DMA może już spokojnie wykonać transfer poprzez SPI. W każdym razie zrobienie takiej transmisji bez udziału procesora to ciekawe ćwiczenie

Podejmuję wyzwanie 🙂 Zrobiłem research i wygląda, że jest to całkiem znana metoda.

image.thumb.png.3e9cb6e4d64db6f0d039d476c6755dda.png

Tu jest porównanie kilku metod https://deepbluembedded.com/how-to-receive-spi-with-stm32-dma-interrupt/ ale bez szczegółów implementacyjnych. W części SPI Transmitter With Timer + DMA (Periodic) jest link do artykułu, który porusza nieco inny temat więc może na później: https://deepbluembedded.com/stm32-change-pwm-duty-cycle-with-dma-for-sine-wave-generation/

Zauważyłem że dobre hasło to "STM32 external ADC SPI DMA", jest to najwyraźniej typowy przykład użycia zewnętrznych przetworników ADC z sygnałem Ready. Przykładowo tu https://stackoverflow.com/questions/52373065/stm32-spi-dma-transferring-at-external-interrupt identyczny problem ale odpowiedzi nijakie:

Cytat

On other STM32 controllers you can select the DMA trigger interrupt to be e.g. a timer overflow. Problem is, after the trigger has started your first DMA transfer it has to be changed to SPI RX buffer empty trigger which can not be done automatically.

Also you have to check if the EXT Pin interrupt can be used as a DMA trigger.

Chyba najbardziej trafny wpis to ten: https://community.st.com/s/question/0D50X00009q4MRTSA2/stmf4-external-interrupt-dma-20bit-spi-xfer-completion-interrupt-to-isr

Jest tu konkret:

image.thumb.png.96f3e24a53df63c3e580884fb1350901.png

Niestety niezabardzo go rozumiem, musze się jeszcze poduczyć na prostszych przykładach.

To wygląda prościej, jak użyć ETR doszedłem z kursem na blogu 🙂  Później przetestuję: https://blog.fearcat.in/a?ID=01650-2af53e9c-1770-4223-ac15-aa3c458f4045

Cytat

The method we take is to use TIM3, set it to ETR counting mode (1 pulse number), and connect DRDY to the TIM3_ETR input pin. Once the falling edge of DRDY arrives, TIM3 counts a pulse and generates the internal trigger signal TRGO. And start a DMA by this signal, use it to trigger the DMA transmission that SPI sends.

 

 

 

image.png

image.png

 

Edytowano przez Gieneq
  • Lubię! 1
Link do komentarza
Share on other sites

Doszedłem do wniosku, że i tak potrzebuję przerwanie, bo każda próbka musi zostać zapisana do bufora, więc na razie zostaję przy wersji w której przy przerwaniu od pinu DRDY (o wyższym priorytecie) jest rozpoczynany transfer SPI z DMA. 

Tylko w takim układzie nie uda się wyciągnąć 30kHz, bo transmisja się nie wyrabia. Zegar SPI ustawiony na 2MHz to max, ale problem jest w ogromnym czasie pomiędzy przerwaniem a rozpoczęciem transmisji:

image.thumb.png.56c3d456988adf3793e869cee16a0504.png

Zaglądając do wnętrza funkcji HAL widać że sporo się tam dzieje. Jest to zgodne z opiniami: https://stackoverflow.com/questions/52805707/how-to-decrease-spi-overhead-time-for-stm32l4-hal-library

Cytat

HAL is hopelessly overcomplicated for time-critical tasks (among others). Just look at the HAL_SPI_Transmit() function, it's over 60 lines of code till it gets to actually touching the Data Register.

Także spróbuję trochę to uprościć. 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

@Gieneq Przerwanie jak najbardziej, ale po a nie przed transmisją. Czyli DMA powinno wykonać odczyt, a jak skończy to generowane jest przerwanie. Konfigurując DMA w trybie circular z przerwaniem w połowie mamy sporo czasu na obsługę przerwania, więc kolejny transfer może się rozpocząc nawet podczas wykonywanie procedury obsługi przerwania od poprzedniego.

A co do ilości kodu w bibliotece HAL... to delikatnie mówiąc jest mało optymalna, SPI dla Arduino jest o wiele lepiej napisane. Więc jeśli w przerwaniu dopiero konfigurujesz transfer przez SPI to musi trwać wieki. Można użyć LL, ale najlepszym rozwiązaniem będzie wykorzystanie sprzętu, więc DMA, a przerwania na koniec. I wtedy nawet "niezbyt idealny" HAL da radę.

Edytowano przez Elvis
  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.