Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

ATMEGA4809 CURIOSITY NANO

tmf 14 Nov 2021 22:00 2559 18
IGE-XAO
  • ATMEGA4809 CURIOSITY NANO
    Mikrokontrolery AVR cieszą się niezmienną popularnością, ze względu na swoją prostotę, a jednocześnie spore możliwości. Co ciekawe, mimo, że od lat wszyscy wieszczą rychłą śmierć mikrokontrolerów 8-bitowych, mają się one ciągle dobrze, a kolejne, nowe rodziny są wprowadzane na rynek. Jakiś czas temu Microchip wprowadził na rynek nową rodzinę mikrokontrolerów ATMega. Przeszły one spory lifting, m.in. wzbogacono poczciwe ATMegi o nowe peryferia znane z serii XMEGA, jednocześnie upraszczając je nieco, co z pewnością ułatwi migrację.
    Z kilku istotnych cech nowej serii ATMega wymieniłbym:
    - płaska przestrzeń adresowa – jak pamiętamy AVRy od zawsze miały dwie, oddzielne przestrzenie adresowe – FLASH zawierający pamięć programu oraz SRAM zawierający modyfikowalne dane. Obie przestrzenie były rozdzielne, co przyprawiało programistów piszących w C/C++ o ból głowy – wszyscy pamiętamy słynne PROGMEM, pgm_raad_XX, __flash, __memx itd. Z tym już koniec – wspólna przestrzeń adresowa powoduje, że już nie musimy się przejmować gdzie co jest.
    - event system – dla niezorientowanych jest to układ umożliwiający połączenie ze sobą różnych peryferii MCU, w efekcie mogą one współpracować, bez zaangażowania CPU. Np. zdarzenie na pinie może wyzwolić timer, ADC lub inny układ peryferyjny co nie tylko odbywa się bez udziału CPU, ale czas od zdarzenia do efektu jest stały.
    - z peryferii mamy do pięciu 16-bitowych timerów, do 4 UART/USART, 10-bitowy ADC z 16-kanałowym multiplekserem analogowym no i pozostałe znane nam peryferia, czyli niestety nic nowego, ale za to mamy 5 wbudowanych źródeł nap. referencyjnego + Vcc.
    - programowalny układ logiczny z 4 tablicami LUT umożliwiający realizację funkcji przerzutników typu D, JK lub zatrzasków typu D lub RS oraz oczywiście kombinatoryki opartej na LUT. To wszystko jest spięte przez event system z pozostałymi peryferiami, dając w efekcie elastyczne narzędzie, które można ciekawie wykorzystać.
    - maksymalne taktowanie to tylko 20 MHZ – szkoda, bo jest to wyraźny krok wstecz, w stosunku do 32 MHz XMEGA.
    - znany z XMEGA kontroler pamięci NVM, user i signature row do przechowywania danych konfiguracyjnych, unikalne numery seryjne i inne rzeczy znane z XMEGA.
    - kontroler NVM umożliwia płynne ustawienia rozmiaru pamięci bootloadera, co może być pomocne – w jednym z projektów musiałem użyć MCU z dwukrotnie większym FLASH tylko dlatego, żeby zmieścić bootloader, w tej rodzinie, wystarczy zmienić ustawienia jednego z rejestrów.
    - elastyczny system zegarów – mamy 5 zegarów + preskaler, dzięki czemu, każdy odnajdzie pożądaną przez siebie częstotliwość.
    - rozbudowany zegar RTC.
    Rodzina ta produkowana jest w obudowach od 28 do 48 pinów, posiada do 48 kB FLASH i do 6 kB SRAM. Dla początkujących hobbystów ważne jest, że procesory te produkowane są także w obudowie DIP, co umożliwia ich wykorzystanie z płytkami stykowymi i proste lutowanie (ja osobiście wolę SMD ale skoro mamy te MCU w DIP, TQFP, QFN i SSOP to każdy znajdzie coś dla siebie). Osoby znające XMEGA nie będą miały problemów z przesiadką na te MCU i odnajdą tu znany z XMEGA styl opisu peryferiów. Niestety, nie znajdą tu też nic nowego w stosunku do XMEGA, poza programowalną logiką znaną z rodziny E5 i zasilaniem do 5V. Z drugiej strony, to proste MCU i jeśli ktoś potrzebuje wodotrysków to przejście na ARM wydaje się być rozwiązaniem.
    CURIOSITY NANO
    Ale wróćmy do płytki ATMEGA4809 CURIOSITY NANO. Na samym początku – cena jest taka sobie, jakiś czas temu były różne promocje, niestety na dzisiaj kosztuje 16,37 Euro w sklepie Microchipa, w popularnych sklepach cena to ok. 92-100 zł. Trochę sporo, być może jest to związane z ogólnym szaleństwem na rynku półprzewodników. A co w tej cenie dostajemy?
    W niewielkim pudełku (a raczej pudełeczku) znajdziemy niepozorną płytkę (ale o całkiem sporych możliwościach) oraz dwie listwy kołkowe. Zacznijmy od tych ostatnich – aby skorzystać z dobrodziejstw tej płytki musimy ją połączyć z resztą komponentów (sama płytka nie zawiera nic ciekawego – po prostu goły MCU z wyprowadzonymi pinami oraz debugger/programator). Stąd też wydaje mi się, że zabawę z modułem warto rozpocząć od przylutowania dołączonych listew kołkowych. Najprościej – włożyć je w płytkę stykową, wsunąć pomiędzy nie płytkę curiosity i przylutować – całość potrwa jakieś 2 minuty, a dzięki wstawieniu listew w płytkę stykową wszystko mamy ładnie unieruchomione podczas lutowania i co najważniejsze – mamy gwarancję, że listwy przylutujemy prosto.
    Sama płytka jest niepozorna – zawiera procesor ATMega4809, przycisk, jednego LEDa i kwarc 32k do taktowania wbudowanego w MCU układu RTC. Ale to nie wszystko – zawiera jeszcze jeden komponent, bez którego w ogóle nie zadawałbym sobie trudu opisywania tej płytki – a jest nim programator/debugger. Co ciekawe jest on zbudowany w oparciu o znacznie potężniejszy procesor ARM – SAM D21 ze stajni Microchipa. Dzięki temu cały moduł możemy podłączyć do PC i od razu rozpocząć zabawę. Nie jest potrzebny żaden zewnętrzny programator. Co więcej, znajdujący się na pokładzie programator/debugger możemy użyć także do programowania innych układów. Poprzez to samo USB mamy też wirtualny port szeregowy (RS232), umożliwiający komunikację pomiędzy MCU (ATMega) a PC.
    Aby rozpocząć zabawę potrzebujemy jeszcze jedno – musimy ściągnąć darmowe programy – Microchip Studio lub MPLAB X. Oba to kompletne środowiska zintegrowane, zawierające edytor, kompilator i wszystko co potrzebne, aby rozpocząć zabawę z MCU.
    Microchip Studio można pobrać stąd – https://www.microchip.com/en-us/development-t...ware/microchip-studio-for-avr-and-sam-devices
    A MPLAB X stąd – https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide
    Ja używam Microchip Studio i dalej pokażę wszystko na przykładzie tego IDE.
    Pierwsze podłączenie
    Przed podłączeniem Curiosity do PC warto odpalić Mictorchip Studio. Dzięki temu po podłączeniu płytki, zostanie ona automatycznie rozpoznana, a nam się ukaże strona zawierająca wszystkie informacje o naszej nowej płytce:
    ATMEGA4809 CURIOSITY NANO
    Dodatkowo Windows otworzy okno, w którym zobaczymy kilka plików:
    ATMEGA4809 CURIOSITY NANO
    Jest to pewna ciekawostka i nowość w stosunku do wcześniejszych płytek Microchipa, które również zawierały wbudowany debugger. Ponieważ w tym przypadku debuger/programator zbudowany jest w oparciu o w miarę „mocny” procesor, oferuje on kilka możliwości – m.in. programowania ATMegi poprzez proste przeciągnięcie pliku hex z PC do otwartego okna CURIOSITY. W ten sposób możemy programować płytkę metodą drag&drop, co może być przydatne jeśli nie korzystamy z firmowego IDE lub mamy gotowe pliki hex ściągnięte np. z Internetu – w takiej sytuacji nie musimy instalować IDE. Właściwie nic nie musimy mieć – po prostu upuszczamy wybrany plik na CURIOSITY i gotowe – MCU jest zaprogramowany i realizuje program. Niestety rozpoznawany jest wyłącznie format IntelHEX, nie są rozpoznawane pliki w formacie elf – szkoda, bo są one wygodne – zawierają wszystkie informacje potrzebne do zaprogramowania MCU – zawartość FLASH, EEPROM, fuse- i lockbitów.
    Oczywiście jeśli korzystamy z IDE to programowanie odbywa się klasycznie, bezpośrednio z IDE.
    Postanowiłem sprawdzić nowy sposób programowania układu, tworząc prosty programik, który przy okazji wykorzystuje jedną z niewielu wbudowanych w płytkę rzeczy – diodę LED, którą będzie cyklicznie migał:
    Code: c
    Log in, to see the code

    Przy okazji na powyższym przykładzie widać, że struktura definicji IO umożliwiających dostęp do peryferii MCU wygląda identycznie jak dla XMEGA. Dodatkowo widać, że tak jak w przypadku XMEGA możliwy jest atomowy dostęp do pinów IO oraz pewne dodatkowe bajery – realizujemy je przez rejestry SET, CLR i TGL przyporządkowane do portu IO.
    Sama płytka ma wyprowadzone wszystkie piny IO procesora, przy czym trzeba pamiętać, że niektóre z nich (PF0-PF3 oraz PB0-PB1) wykorzystywane są do realizacji także innych funkcji – podłączenia oscylatora RTC lub komunikacji z PC poprzez wirtualny UART. Jeśli z jakiś powodów piny te chcemy wykorzystać to należy przeciąć przygotowane na płytce odpowiednie punkty.
    Ogólne wrażenia
    Co tu wiele pisać – wszystko działa od strzału, bez najmniejszych problemów. Z pewnością przydatne jest, że po podłączeniu modułu jest on automatycznie rozpoznawany przez IDE, dostajemy od razu linki do strony z opisem procesora, schematami modułu i innymi informacjami. Programowanie zarówno poprzez IDE, jak i metodą przeciągnij i upuść jest bezproblemowe. Po prostu wszystko działa jak należy i nie ma się do czego przyczepić. Na plus można potraktować także wyprowadzenie wszystkich pinów MCU, dzięki czemu płytkę można potraktować jako procesor z podłączonym na stałe programatorem/debugerem.
    Czy warto?
    Trudno odpowiedzieć na to pytanie. Z pewnością osoba początkująca będzie mogła łatwo wejść w świat mikrokontrolerów, po zainstalowaniu IDE właściwie wszystko dzieje się automatycznie, mamy dużo przykładów – ale te raczej przydadzą się bardziej zaawansowanym użytkownikom.
    Osoby zaznajomione ze starymi AVRami będą musiały trochę się przestawić na nową składnię definicji IO – taką jaką spotkamy w przypadku XMEGA. Ogólnie warto bo moim zdaniem jest ona bardziej przejrzysta, poza tym jest ona spójna z innymi procesorami AVR – rodziną Dx (DA, DB, itd.), które oferują wiele ciekawych funkcji. Szkoda niestety, że obecnie mamy ceny raczej spore – jeszcze rok temu płytka ta kosztowała ok. 60 zł, co byłoby ceną w miarę ok. Jednak mimo wszystko, jeśli ktoś chce poznać te procesory, to z pewnością płytka ta jest warta swojej ceny.
    Warto też dodać, że płytki w formacie nano można wykorzystywać w połączeniu z CURIOSITY NANO BASE – czymś w rodzaju płyty głównej, w którą można wtykać inne moduły. Jest to ciekawa platforma do prototypowania, umożliwiająca uniknięcie plątaniny połączeń znanej z płytek stykowych.
    Mo i jak zawsze – dostępny na płytce programator, a szczególnie debugger jest nie do przecenienia. Osoby, które z tego skorzystają z pewnością nie wrócą już do starych rozwiązań w których o debugowaniu można było pomarzyć, a programowanie odbywało się za pomocą USBAsp.

    Cool? Ranking DIY
    Can you write similar article? Send message to me and you will get SD card 64GB.
    About Author
    tmf
    Moderator of Microcontroller designs
    Offline 
  • IGE-XAO
  • #2
    paluszasty
    Level 25  
    Piszesz o płaskiej przestrzeni adresowej która występuje w megaAVR seri0, AVR DA, AVR DB i tinyAVR seri 1.
    Czy dobrze rozumiem jak to działa:
    - żeby zapisać zmienną dajmy na to we Flash dalej musimy makrodefinicji PROGMEM (lub jakoś inaczej poinformowac kompilator pod jakim adresem na znajdowac się zmienna. Kompilator musi w jakiś sposób wiedzieć o offsecie adresu. ) i deklarować to tak:
    const int a PROGMEM =10;
    -żeby odczytać zmienną a jak przypuszczam nie trzeba już korzystać z funkcji pgm_raad i innych potworków do odczytu zmiennej (stałej) deklarowanej we Flashu. Bezpośrednie odwołania będzie działać.
    Czy może trzeba napisać sobie do tego samemu jakieś funkcje?
  • #3
    tmf
    Moderator of Microcontroller designs
    @paluszasty - muszę sprawdzić jak to zaimplementowali, ale generalnie nic nie powinno być potrzebne. Jeśli zadeklarujesz zmienną z const to powinna ona trafiś do segmentu .rodata, który znajduje się we FLASH. Czyli powinno to wyglądać dokładnie tak jak np. na ARM.
  • IGE-XAO
  • #4
    paluszasty
    Level 25  
    tmf- jestem ciekawy co znajdziesz.
    Ja szukałem i po za dokumentem takim jak ten (i analogiczne chyba dla AVR DA czy megaAVR seri 0):
    https://www.microchip.com/content/dam/mchp/do...ashandEEPROMonthetinyAVR1-series40001983A.pdf
    to niewiele znalazłem i z tego niewiele wynika. Ten manual jest użyteczny jak by ktoś chciał pisać bootloader który opisany jest np tutaj:
    https://ww1.microchip.com/downloads/en/Appnot...tloader-for-tinyAVR-and-megaAVR-00002634C.pdf

    Jeśli jest tak jak mówisz i wszystkie zmienne zadeklarowane jako const są zapisywane we Flash to rzeczywiście bardzo upraszcza to pisanie programów. Chyba że z jakiegoś powodu chcemy umieścić zmienne zadeklarowane jako const w RAMie, jak wtedy to zrobić?
    Natomiast co z danymi które chcemy zapisać EEPROM?

    Dodano po 38 [minuty]:

    Męcząc temat dalej znalazłem coś takiego:
    https://www.avrfreaks.net/comment/2596841
    W poście #153 jest częściowa odpowiedź.
    Wygląda na to że znajdą się w pamieci FLASH tylko jeśli będą zadeklarowane po prostu jako const (const char s[]="...").
    Jeśli użyjemy jakiejś opcji:
    const char PROGMEM p[] = "...";
    const char __attribute__((section(".text"))) t[] = "...";
    const char __flash f[] = "...";
    To zgodnie z :
    https://tomalmy.com/addressing-in-the-atmega4809/
    to dane lądują one w jakieś rejestrach "Ext I/O"
  • #5
    tmf
    Moderator of Microcontroller designs
    @paluszasty Właśnie sprawdzałem jak wygląda kwestia dostępu do FLASH i jest tak jak pisałem. Definiujesz stałą z const i automatycznie ląduje ona we FLASH, a z programu masz do niej dostęp bez żadnych specjalnych udziwnień. Czyli definicja:
    const char tmpchar1[] = "test";
    trafia do FLASH, skąd można ją czytać normalnie, bez makr pgm.
    paluszasty wrote:
    Chyba że z jakiegoś powodu chcemy umieścić zmienne zadeklarowane jako const w RAMie, jak wtedy to zrobić?

    Ale po co chciałbyś tak robić? To nie ma sensu (o ile timingi dostępu do SRAM nie są krótsze). Jeśli byś się uparł to możesz jawnie wskazać segment do którego dana zmienna ma być załadowana.
    Co do EEPROM - zapis będzie wymagał specjalnych funkcji, bo to zapis do pamięci, która jest głównie do odczytu i podzielona na bloki. Natomiast odczyt możliwy jest podobnie jak w XMEGA bezpośrednio, bez żadnych makr/funkcji, gdyż EEPROM też jest zmapowany w normalną przestrzeń adresową MCU.
  • #6
    mpier
    Level 26  
    @paluszasty, dla normalnego użytkownika z tego co widzę różnica jest chyba tylko na poziomie assemblera. Teraz dla popularnego attiny13 możesz zrobić tak:
    Code: c
    Log in, to see the code
    Teraz f3() i f3a() są uniwersalne, ale na attiny13 o dwie instrukcje dłuższe.

    Pewnie debugger (firmware) robi cenę, bo podobne arduino nano every jest sporo tańsze.
  • #7
    Janusz_kk
    Level 32  
    mpier wrote:
    Pewnie debugger (firmware) robi cenę, bo podobne arduino nano every jest sporo tańsze.

    Ale zawartość sprzętowa prawie taka sama, też ma SAM-a do programowania. W botlandzie teraz znalazłem za 54zł.
  • #8
    Karol966
    Level 30  
    tmf wrote:
    z ogólnym szaleństwem na rynku półprzewodników
    Nie pamiętam dokładnie ale coś mi świta, że w TME kupiłem tą płytkę (dość dawno, minimum na początku br lub nawet w ubiegłym) za ok 40-50zł. Nie wiem do czego służą te lekko pofalowane otwory przy krawędzi ale jak tam się wciśnie listwę goldpin to bez lutowania się dobrze trzyma ;)
    Sam kupiłem tą płytkę, gdy jeszcze miała miano najtańszego debugera do kupienia (z gratisowym prockiem).

    PS. Czy wraz z nowymi procesorami (lub nawet starymi ale nowszymi od pierwszych wydań AVRów) wychodzą jakieś aktualizacje lub podobne rozwiązania jak AVR231? Nie czuję się na siłach (lub po prostu nic mnie jeszcze nie zmusiło do tego) aby napisać samodzielnie szyfrowany bootloader, tym bardziej gdy np do dyspozycji jest USB. Stąd wciąż tkwię w starych AVRach :/
  • #9
    tmf
    Moderator of Microcontroller designs
    Karol966 wrote:
    Czy wraz z nowymi procesorami (lub nawet starymi ale nowszymi od pierwszych wydań AVRów) wychodzą jakieś aktualizacje lub podobne rozwiązania jak AVR231?

    Do tej noty jest kod źródłowy - wystarczy go tylko lekko zmodyfikować. Są bootloadery do nowszych procków, ale nie widziałem, aby microchip udostępniał ich kody źródłowe.
    Karol966 wrote:
    ym bardziej gdy np do dyspozycji jest USB. Stąd wciąż tkwię w starych AVRach

    Tu jest mały problem bo stos USB jest raczej obszerny - implementacja na AVR to co najmniej kilka kB - czyli więcej niż obszar bootloadera dla większości AVR. Stąd nowa cecha nowych rodzin AVR polegająca na płynnym określeniu wielkości bootloadera jest bardzo fajna, tyle, że one nie mają USB :)
  • #10
    abant
    Level 11  
    tmf wrote:

    paluszasty wrote:
    Chyba że z jakiegoś powodu chcemy umieścić zmienne zadeklarowane jako const w RAMie, jak wtedy to zrobić?

    Ale po co chciałbyś tak robić? To nie ma sensu (o ile timingi dostępu do SRAM nie są krótsze).


    Ja na przykład często tak deklaruję zmienne pomocnicze w funkcjach, które mają przypisaną wartość w momencie wywołania i nie mają być modyfikowane w trakcie jej wykonania.
    Dzięki temu kompilator ma łatwiej z optymalizacją (nie wiem, czy to wykorzystuje)
    a ja modyfikując tę funkcję po jakimś czasie lub po kimś,
    wiem, czego nie powinienem zmienać.

    Kompilatory których używałem najczęściej były na tyle inteligentne, że jeśli wartość zmiennej była możliwa do określenia na etapie kompilacji trafiała do flash, a jeśli nie do RAM.

    Albert
  • #11
    tmf
    Moderator of Microcontroller designs
    abant wrote:
    Ja na przykład często tak deklaruję zmienne pomocnicze w funkcjach, które mają przypisaną wartość w momencie wywołania i nie mają być modyfikowane w trakcie jej wykonania.

    Tak, ale jakie miałoby znaczenie, czy taka zmienna byłaby w RAM, czy we FLASH? Skoro jest const to nie można jej modyfikować.
    abant wrote:
    Kompilatory których używałem najczęściej były na tyle inteligentne, że jeśli wartość zmiennej była możliwa do określenia na etapie kompilacji trafiała do flash, a jeśli nie do RAM.

    avr-gcc jest na tyle inteligentny :)
  • #12
    abant
    Level 11  
    Nie bardzo rozumiem Twoje zastrzeżenia.

    1 Chcę, żeby zmienna była w RAM (nie może być we flash, bo przy każdym wywołaniu ma inną wartość)
    2. Chcę, żeby była const ( aby kompilator pilnował, aby ktoś modyfikując funkcję nie zmienił jej wartości)
    Czyli przypadek, który uznawałeś za mało sensowny.

    Próbuję uzasadnić dlaczego uważam inaczej i używam takiej konstrukcji.

    Ty bez podważania moich racji piszesz ze nie ma to znaczenia. WTF?

    Albert
  • #13
    mpier
    Level 26  
    W domyśle chodzi o dane statyczne, nie o zmienne na stosie.
  • #14
    tmf
    Moderator of Microcontroller designs
    abant wrote:
    1 Chcę, żeby zmienna była w RAM (nie może być we flash, bo przy każdym wywołaniu ma inną wartość)
    2. Chcę, żeby była const ( aby kompilator pilnował, aby ktoś modyfikując funkcję nie zmienił jej wartości)

    A możesz wstawić kod ilustrujący takie działanie? Bo nie widzę w jaki sposób zmienna const mogłaby być modyfikowana pomiędzy wywołaniami funkcji.
  • #15
    abant
    Level 11  
    No cóż, nie spodziewałem się, że będziesz miał z tym problem. Proszę:
    Code: c
    Log in, to see the code
  • #16
    tmf
    Moderator of Microcontroller designs
    Ale w powyższym przykładzie:
    const uint32_t delta = b*b-4*a*c;
    zmienna nie znajdzie się we FLASH, gdyż jej wrtość nie jest znana na etapie kompilacji, chyba, że gcc zoptymalizuje wywołanie funkcji i stworzy jej klona - wyspecjalizowaną wersję dla określonych wartości argumentów. Ale niezależnie od tego nie będzie miało znaczenia, czy jest w FLASH, czy RAM.
    Natomiast co do tego:
    delta = 5; // Compilet error, niby oczywiste ale:
    libFunction (&delta); // chcę mieć pewność, że to wywołanie nie łamie moich założeń co do delta
    to kompilator wygeneruje błąd bo delta jest const, więc nie da się jej przypisać wartości w inny sposób niż w czasie deklaracji, która jest jednocześnie definicją. Z kolei przekazanie adresu delta (&delta) do funkcji też będzie możliwe o ile ta funkcja przyjmuje jako argument wskaźnik na const - a jeśli tak będzie to znowu nie ma znaczenia czy funkcja jest w RAM, czy FLASH.
    Natomiast jeśli chcesz przekazując adres na funkcję po ciuchu pozbyć się const, to jest to niezgodne z językiem i daje niezdefiniowane rezultaty. Tak samo będzie na ARM, z tym, że tam pewnie skończy się to wyjątkiem.
  • #17
    abant
    Level 11  
    Więc opisujesz dokładnie to co ja chcę uzyskać, i dlaczego taką konstrukcję stosuję.
    a Ty uważasz za bezsensowne. (const w RAM) patrz post #5
    Dlatego dalej nie rozumiem Twoich intencji w tej dyskusji.

    Albert
  • #18
    tmf
    Moderator of Microcontroller designs
    Pytanie brzmiało - Chyba że z jakiegoś powodu chcemy umieścić zmienne zadeklarowane jako const w RAMie, jak wtedy to zrobić?
    Odpowiedź - nic, bo nie ma to sensu. Kompilator o tym decyduje sam i nie ma potrzeby aby coś ręcznie ustawiać, a taki był chyba kontekst pytania.
  • #19
    abant
    Level 11  
    OK. Twoja odpowiedź w #5 była sformułowana nieintuicyjne.
    Uznaję wszystko za wyjaśnione. Pozdrawiam.