A napiecie za LDO roslo powoli? Bo u mnie lockup jest dosc powtarzalny - musialem zadbac o dobre zasilanie.
Z drugiej strony - pierwszy procek Atmela jaki uzylem i dosc duza wpadka (poza tym nie nowa - Altera to miala z 5 lat temu z Cyclonami).
A napiecie za LDO roslo powoli? Bo u mnie lockup jest dosc powtarzalny - musialem zadbac o dobre zasilanie.
Z drugiej strony - pierwszy procek Atmela jaki uzylem i dosc duza wpadka (poza tym nie nowa - Altera to miala z 5 lat temu z Cyclonami).
Bardzo wolno. Powoli kręciłem zasilaczem od 0 do 5V. Napięcie 5V narastało powoli, za LDO 3,3V też powoli, napięcie 1,8V z VDDOUT powoli. Nóżka reset bez zewnętrznego układu reset (rezystor 10k, kondensator 100nF, dioda BAS85 równolegle do rezystora). Na resecie napięcie też narastało powoli. Procek za każdym razem prawidłowo startuje. (używam 32UC3B0256).
Po testach z AT91SAM7S64 doszukałem się w PDFie takiego zdania:
"During startup, core supply voltage (VDDCORE) slope must be superior or equal to 6V/ms."
Oczywiście już po tym jak gotowy prototyp i brałem się za jego oprogramowanie :)
SM
SM przemówił ludzkim głosem:
A to że host wysyła pakiety do urządzenia co 1ms, to już ci nie przeszkadza? Albo to, że program na PC może być wywłaszczony na dowolnie długi czas i nic ci nie wyśle?
A co ma jedno z drugim wspólnego? Przecież pisałem o czasie oczekiwania na odpowiedź, a nie o tym że czas pomiędzy dwoma pakietami SOF to 1ms. Skąd w takim razie ograniczenie oczekiwania na odpowiedź do 18 bitów? No chyba że chodzi tu o odpowiedź sprzętowego kontrolera USB w procku, a nie mojego softu obsługującego USB.
Czyli mam liczyć na to że program obsługujący będzie "przyhamowywany" i tylko dlatego soft będzie działał.
SM
SM przemówił ludzkim głosem:
Oczywiście, to kontroler zajmuje się sygnalizacją, czy ma coś w buforze do wysłania, czy nie.
Tak to napisałeś jakby twój soft musiał dostawać nowe dane z dokładnością co do us. Jeśli tak nie jest to ok.
Zbych pisze:
No to chyba się kompletnie nie rozumiemy.
Przykład:
Sterownik USB w uC informuje mnie, że odebrał dane - czyli pakiet "In Token". Ja te dane interpretuje i odsyłam "Data". I pytanie - jak długo Host czeka na odpowiedź od urządzenia?
W książce wyczytałem: "Czas pomiędzy dwoma kolejnymi pakietami SOF nazywany jest ramką". Ramka wynosi 1ms. Czyli wnioskuję że Host wysyła pakiet "In Token" poprzedzony przez SOF. Ja odpowiadam "Data" również z nagłówkiem SOF, ale nie w tej samej 1ms bo między dwoma pakietami SOF ma być 1ms przerwy (czyli ramka). Ale dalej czytam: "Stąd wyrażone w bitach maksymnalne opóźnienie w dotarciu odpowiedzi do gosta wynosi 16 bitów. Właśnie to opóźnienie jest podstawą do określenia ograniczenia czasowego oczekiwania na odpowiedź w urządzeniu nadającym". W wcześniej: w najgorszym przypadku przejście przez 5 hubów może zająć 350ns. "Ostatni hub przesyła pakiet do urządzenia, które po jego odebraniu i sprawdzeniu wysyła odpowiedź. SPECYFIKACJA PODAJE, że czas na WYMIENIONE OPERACJE liczony od momentu dotarcia odpowiedzi do huba [...] nie może przekroczyć 7,5 bitu."
No to zaczynam nie całkiem rozumieć o co tu chodzi.
SM
SM przemówił ludzkim głosem:
Jeśli nie zdążysz wstawić do bufora danych to kontroler wyśle informację, że nic nie ma do wysłania. Tym steruje sprzęt, więc nie ma co się przejmować czy zdążysz. Za 1ms host ponowi pytanie. Jeśli wtedy będzie coś w buforze, to kontroler to wyśle.
...chodzi o czas Round-Trip Delay wynoszący 1,5us.
"The maximum length of a standard USB cable is 5.0 meters (16.4 ft). The primary reason for this limit is the maximum allowed round-trip delay of about 1500 ns. If a USB device does not answer to host commands within the allowed time, the host considers the command to be lost."
"The USB Specification allows a maximum period of approximately 1.5 microseconds for the round-trip delay of a single communication from a host computer to a device and back to the computer"
Jeśli urządzenie USB nie odpowie Hostowi USB w czasie 1,5us, Host uznaje komendę za "straconą" (nie odebraną).
Właśnie tym czasem się martwię. W 1,5us muszę odebrać dane od sterownika USB w uC, zanalizować je, i odesłać odpowiedź. Ponieważ mogę być za 5-tym Hubem to na wszystko pozostaje mi
7,5 bitu * 83ns (FullSpeed) 623ns!!!SM
SM przemówił ludzkim głosem:
Nie musisz. Dane mogą pójść do hosta przy następnej ramce.
Aaaa no to teraz jasne. Bałem się że sterownik USB w uC musi dostać dane wtedy kiedy chce tego host, a potem one przepadają.
Ale jak tak, no to spoko. W razie czego będę miał komunikcję co drugą ramkę i tyle.
Dzięki, SM
Znowu trochę posiedziałem nad prockiem. Ale masakra. Chyba z żadnym prockiem nie miałem tyle kombinowania (chociażby ze samą strukturą programu że asembler i linker poprawnie przygotowali dane do ładowania do procka). Skonfigurowałem procka, ruszyłem przerwania na timerze.
Wszystko lekko rąbnięte przez sam fakt, że Atmel dał flash od adresu 0x80000000 a to w integer jest liczba ujemna! Asembler głupieje przy bezpośrednim ustawieniu sekcji org na ten adres, bo dla niego to liczba ujemna i stwierdza że kompilacja odbywa się w ujemną stronę. Trzeba więc robić offset w linkerze. Ale tu kolejny zgrzyt bo stałe zdefiniowane jako różnica adresów wychodzą wtedy Linkerowi błędnie (np. offset autoprzerwania względem EVBA).
Ostatecznie rozwiązałem to tak:
// =========================================================================== // Start of data memory. // ===========================================================================
.section .bss, "", @nobits .org 0
stack_beg: .skip 256 stack_end:
// =========================================================================== // Start of program memory. // ===========================================================================
.section .text, "ax", @progbits
.global _start
_start: .incbin "isp.bin" // original bootloader saved from flash memory
// =========================================================================== // Ints vectors. // ===========================================================================
StartEVBA:
program_begin: rjmp program_start
rjmp Int0Handler rjmp Int1Handler rjmp Int2Handler rjmp Int3Handler
.equ Int0Offset, 4 >> 1 .equ Int1Offset, 8 >> 1 .equ Int2Offset, 12 >> 1 .equ Int3Offset, 16 >> 1
// =========================================================================== // Timer 0 interrupt. // ===========================================================================
Int0Handler:
// reset int flag
mov.w r8, TC0_BASE ld.w r9, r8[TC_SR]
// change PA3 pin
mov.w r8, LBM_BASE mov r9, (1 << 3) st.w r8[LBM_OVR0T], r9
// int exit
rete
// =========================================================================== // Program start. // ===========================================================================
program_start:
// --- stack
mov.w sp, stack_end
****************************************************************************i ustawiam:
// set EVBA pointer
mov.w r0, StartEVBA mtsr SYSREG_EVBA, r0
// set autovector offset for group 14
mov.w r0, INTC_BASE mov.w r1, Int0Offset st.w r0[INTC_IPR0 + 4*14], r1
i oczywiście wszystko działa, ale ile musiałem czasu stracić żeby coś tak prostego zrobić.
Nie mogli dać flasha od 0x40000000. Przeciez mieliby wtedy 1GB na rozbudowę RAM i 1GB (minus rejestry) na FLASH.
SM
Mam zrobione USB CDC więc mogę podać "wyniki":
Całość w ASMie i jednej pętli. Program wygląda tak:
Na starcie: Inicjalizacja procka (flahs, clock,...). Inicjalizacja timera 0 (i przerwań). Inicjalizacja USART. Inicjalizacja USB.
W głównej pętli: Obsługa USART Obsługa USB
Program to co odbierze na USB wysyła na USART, to co odbierze na USART wysyła na USB.
Poza główną pętla obsługa przerwania od timera 0 co 1ms (tak dla celów testowo-poznawczych przerwań)
Całość (razem ze strukturami USB) zajęła mi 1920 bajtów.
SM
SM pisze:
No to teraz przerób główną pętlę na przerwania aby program mógł robić też coś pożytecznego. Bo zniżenie całego procka AVR32 do roli konwertera USB-RS232 to dla niego zniewaga. :)
Oczywiście nie ma sprawy, aby wrzucić to w przerwanie czy też obsłużyć na dodatkowym tasku, ale ja właśnie mam potrzebę aby główna pętla zajmowała się "mniej ważnymi" operacjami (jak np. transmisja z USB), a najważniejsza część programu będzie wywoływana co dokładnie odmierzany czas - czyli przerwaniu.
Przygotowałem sobie także "środowisko" aby pisać soft na procka w C+ASM. Korzystam z edytora ConTEXT i środowiska GCC.
Te AVR32 spodobały mi się na tyle, że chyba dłużej przy nich zabawię. Przyznaję że wzięła mnie już ochota na stworzenie własnego środowiska i kompilatora dla niego. No chyba że zagłębie się w źródła gcc i go przerobię tak, aby generował kod wynikowy bardziej podobny do sposobu w jaki pisze w asm-ie (chodzi mi przede wszystkim o sposób dostępo do zmiennych globalnych w SRAM. Kompilator używa lddpc, a ja zwykłego ld i adresowanie pośrednie z przesunięciem - poświęcam na to jeden rejestr r7. adresuję r7[adres_zmiennej] - offset jest 16bit więc wystarcza na całe 32KB SRAM. No chyba że jest jakaś opcja gcc która coś takiego potrafi wymusić). Jeszcze się trochę przyjrzę jaki kod generuje gcc.
Ale same AVR32 zaczynają mi się niezmiernie podobać. Mam pomysł na większy (jak sądzę bardzo ciekawy) projekt, ale muszę gdzieś dorwać kilka AT32UC3A3128 w jakiejś rozsądnej cenie.
Pozdrawiam, SM
Oczywiście nie ma sprawy, aby wrzucić to w przerwanie czy też obsłużyć na dodatkowym tasku, ale ja właśnie mam potrzebę aby główna pętla zajmowała się "mniej ważnymi" operacjami (jak np. transmisja z USB), a najważniejsza część programu będzie wywoływana co dokładnie odmierzany czas - czyli przerwaniu.
Przygotowałem sobie także "środowisko" aby pisać soft na procka w C+ASM. Korzystam z edytora ConTEXT i środowiska GCC.
Te AVR32 spodobały mi się na tyle, że chyba dłużej przy nich zabawię. Przyznaję że wzięła mnie już ochota na stworzenie własnego środowiska i kompilatora dla niego. No chyba że zagłębie się w źródła gcc i go przerobię tak, aby generował kod wynikowy bardziej podobny do sposobu w jaki pisze w asm-ie (chodzi mi przede wszystkim o sposób dostępo do zmiennych globalnych w SRAM. Kompilator używa lddpc, a ja zwykłego ld i adresowanie pośrednie z przesunięciem - poświęcam na to jeden rejestr r7. adresuję r7[adres_zmiennej] - offset jest 16bit więc wystarcza na całe 32KB SRAM. No chyba że jest jakaś opcja gcc która coś takiego potrafi wymusić). Jeszcze się trochę przyjrzę jaki kod generuje gcc.
Ale same AVR32 zaczynają mi się niezmiernie podobać. Mam pomysł na większy (jak sądzę bardzo ciekawy) projekt, ale muszę gdzieś dorwać kilka AT32UC3A3128 w jakiejś rozsądnej cenie.
Pozdrawiam, SM
In the darkest hour on Thu, 19 Nov 2009 08:41:33 +0100, SM snipped-for-privacy@korinsj.com.pl> screamed:
Rozmiar nie jest tak istotny, jak czas, który zajęło pisanie.
Rozgryzanie procka - 3dni. USB-CDC - 2dni.
Więc pryszcz, biorąc pod uwagę to że będę używał tej samej mojej procedury USB-CDC w wielu projektach.
Cała obsługa USB-CDC jest niewielka - 460 linii. Pisania dużo nie było. Gorzej z rozgryzaniem procka.
W wolnej chwili zrobię mu test szybkości. Zakupiłem DAC stereo 16bit i zobaczę czy wyrobi się w roli syntezatora FM (emulacja Yamahy DX-7). Jak da radę z polifonią przynajmniej 8 to robię sobie kompletny syntezator na dwóch AVR32 i SDRAMie.
SM
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.