Vieną open-source projektą nupaišiau. Dabar reikia tik palaukti, peržiūrėti, nupaišyti silk screen ir rasti kinus kurie pagamins.
Rankutėmis viskas, rankutėmis.
Vieną open-source projektą nupaišiau. Dabar reikia tik palaukti, peržiūrėti, nupaišyti silk screen ir rasti kinus kurie pagamins.
Rankutėmis viskas, rankutėmis.
Šiaip tai “pilnavertis” modernizuotas Z80 CPU kompiuteris.
Kaip jis gavosi šiais 64 bitų laikais? Vienas žmogus prisiprašė “pažiūrėti” senovišką industrinį kompiuterį. Ten buvo “kažkas” su Z80 procesorium ir stipriai ištekėjusia batareika. Batareika ištekėjo ant PCB, paėdė takelius ir šiaip nieko gero. Kompiuteris modulinis, visi “power” ir jutiklių moduliai kitoje PCB. O nukentėjo tik “kompiuteris”. Jo RAM tai dar ant baisių DRAM mikroschemų, kur reikia egzotinio maitinimo (4116, su -5V ir +12V maitinimu) … ir aišku ten kažkas stipriai neveikia. Parakinėjus daugiau supratau, kad ten šikna ir neverta kažką daryti, nes tai paprasčiausias kompiuteriukas. Taip gimė ši PCB.
Continue reading →
Jau rašiau, kad internetuose radau Rogue žaidimo source code kuris netikėtai susikompiliavo ant mano kompiuterio. Deja ant kitų kompiuterių jis neveikė. Bandžiau tokį iškrypimą, kaip perkelti source code į Microsoft Visual Studio Express, bet ten tikriausiai iš principo negali veikti jokie senoviški C kalbos failai- microsofto programa pranešinėjo keistas klaidas. Numojau į tai ranka ir pagalvojau- jei kompiliuojasi su gcc, tai kodėl jis nesikompiliuoti ir su ARM gcc (AVR tai gal per silpnas). Pasirodo, puikiausiai kompiliuojasi. Teko tik išpjauti dali paprogramiu susijusiu su failais ir prikabinti savo. Taip gavosi toks monstras:
Tai USB-COM-Rogue su STM32F103. Tereikia tik USB terminalo. Po tiekos programinimo, manau UART versija dar greičiau gautusi. Dar beliko viską sukultūrinti, nes dar liko visokių bugų- pvz. po žaidėjo mirties, jis kaip zombis toliau gali vaikščioti po labirintą. Nesvarbu, kad jau parodė mirties ekraną- turėjo pasileisti žaidimas iš naujo, bet kažkaip neišsivalė buferiai ir viskas liko iš seno žaidimo. Visiškai nesupratau dėl TERMCAP failo- vieną įdėjau ir veikia, įdėjau antrą- neveikia. Vėl įdėjau pirmą- neveikia. Veikia tik iš vakar dienos backupo. Originalus source kodas gana užsuktas. Užtat ir ant ARM gcc kompiliuojasi be jokių “warningų”.
Žaidimo source code ir kompiliuotas HEX. Dėmesio! Binaras gaunasi didelis (92kB ir neaišku kiek RAM jam reikia) ir tikrai neveiks ant BluePill. Jis veikia ant mano “white pill“, su pilnaverčiu STM32F106RET6.
Buvo straipsniukas, kaip aš sugadinau Citizen CX-123II kalkuliatorių. O dabar šio straipsniuko pratesimas. Toks ilgas tarpas gavosi todėl, kad aš tik mokinuosi. O ir kažkaip įtariu, kad į Bluepill plokšteles kinai sudėjo kažką mažesnio. Nes kartais labai magiškai projektas pradėdavo daryti nesąmones. Todėl labai ilgam sustojau, nes reikėjo savo PCB pasidaryti ir sunaudoti turimas mikroschemas. Dabar mano testavimui teko didesnė mikroschema STM32F103RET6, kuri rodos turi 512K ROMo ir 64K RAM. Tačiau spėju, kad galutinė programa turi tilpti ir į bluepill, jei tik Kinas labai nepataupė.
Šis “printeris” susideda iš kelių modulių: USB modulio, tarpininko tarp USB printerio ir mano citizeno programos. Šio eksperimento pamoka- USB pertraukimas turi būti mažesnio prioriteto nei machaninio printerio. Taip, mechaninis printeris veikia grynai per pertraukimus ir visi “taimingai” svarbūs.
Deja, šis projektas mano nusibodo- aš pilnai nesupratau, kaip veikia spalvos perjungimas ir pirmo (paskutinio) simbolio spausdinimas. Dabar printeris daro tai, kad jam nurodyta- spausdina skaičiukus iš bet kokio teksto paleisto į printerį. Jis kiek stengiasi filtruoti, tačiau vistiek dažnai spausdina nesąmones. Ir kartais užsispiria ir prispausdina ne to, ką norėjau.
Printeriui užtenka energijos iš USB lizdo. Kad paleisti reikia tik dviejų n-kanalo laukinių tranzų (su 3V tolerantišku valdymu, iš kompiuterio motininės plokštės, gal dviejų diodų. Ant PWM motoro valdymo reikia nedidelio elektrolitinio kondensatoriaus.
Ir aišku visas source kodas ir kompiliuotas binaras. Dėmesio! STM Cube projektas neatitinka pačio kodo, pergeneravus, gali nebesusikompliuoti. Dabar binaras yra skirtas STM32F103RET6 mikroschemai.
Buvo smagu.
Tai projektas kuris pilnai užstrigo dėl mano neprofesionalumo ir dėl dokumentacijos trūkumo. Užduotis- konvertuoti vieną iš STM32CubeMX projektų į printerio klasę (Printer Class). Tam reikalui panaudojau CDC klasę ir perdariau pagal savo seną AVR projektą į printerio klasę. Ir jis, rupužė, neveikia taip kaip reikia.
Ką daro publikuotas projektas:
Kad atkartoti projektą, reikia pradėti STM32CubeMX su USB ir CDC klase. Poto, viską CDC pašalinti ir sudėti mano source. Kas svarbu- “midlevares”- klasė “PRINTER”. Pagrindiniam “src”: usbd_princer_if.c – printerio ryšis su USB, usbd_conf ir usb_desc – ne pilnai išvalyti nuo CDC klasės ir kiek pribūrta dėl MS deskriptoriaus.
Tačiau jei laikyti kodą teisingu, tai useriui reikalingas tik vienas failas- printer_hardware.c. Tai pats fizinis spausdinimas. Šiuo metu nuvestas į USARTą. Prisijungus išorinį UART (COM adapterį) galima lengvai debuginti ir monitorinti kas vyksta.
Dėmesio! Nepergeneruokit kubiko kodo, nes nužudys kai kuriuos failus.
Download STM32CubeMX USB PRINTER CLASS demo code (source and compiled hex for bluepill STM32F103C8.
Kodėl tai sunkiai einasi ir kodėl dedu nepilną kodą? Todėl, kad nėra free programų, kurie lengvai analizuotu kas vyksta ant USB. Todėl, kad dokumentacijos labai mažai- daug kas rašo kodą ir daro aparačiukus kurie naudoją printerius, tačiau visiškai niekas nedaro pačių printerių. Todėl, kad USB.ORG tik apibrėžė klasę, o realiam pasaulyje tiek microsoftas, tie obuolys, tie printerių gamintojai prisigalvojo savo “piblūdų ir navarotų” kuriuos mažai kur viešai publikavo. Ir dar aišku, visiškai nėra laiko tokiems žaidimams, o ir šiaip, nėra tiek žinių, kad greitai perprasti svetimą kodą. Ypač kai kodą rašo narkomanai- vien ko vertas STM inžinierių “universalus” metodas bendrauti tarp usb device, usb interface ir userio kodo per pointerius ir pointerių struktūras. Ar pointerių struktūrų pointerius struktūruose per pointerius ar panašiai 🙂 (gi narkomanai rašė).
O postinu, kad kiti gal pasinaudos, o ir pats turėsiu rezervinę kopiją.
Vieni renka markutes, kiti sprendžia kryžiažodžius. O man kartais patinka pajungti kokį nesąmoningą prietaisą ir sužinoti kaip jis veikia. Šį kartą radau Citizen CX-123II kalkuliatorių. Toks kalkuliatorius moka spausdinti skaičiukus ant popieriaus juostos. O kaip gi tokio “printerio” neprijungus prie kokio nors mikrokontrolerio.
Turim tokį grieką, kad kai žaidžiam žaidimus, žiūrom kokia pornografiją ar šiaip, ir staiga pastebim, kad jau gili naktis. Aišku kažkur yra laikrodukas lentynoje, bet geriau prisukti palei nosį, kad rodytu tuščiai praleistą laiką. 🙂
Tai DIY RTC laikroduko eksperimentas su pačiais pigiausiai komponentais. Kaip tik susirinkti ir ištestuoti. Kogero sunkiausiai bus padaryti korpusą:
Tai laikrodis, kuris nusistato per USB (jokių mygtukų), rodo laiką ir laiką nuo paskutinio įjungimo (uptime). Kadangi maitinasi iš USB, tai rodo kiek laiko pajungtas kompiuteris.
Schema paprasta- “blue pill” modulis, OLED modulis, du rezistoriai po 4K7 ant I2C buso, vienas rodos 270R nuosekliai 1N4148 diodui- krauti super kondensatorių ir aišku pats kondensatorius.
Laikas nusistato per USB. Reikia sužinoti kokį COM portą emuliuoja laikrodis. Pas mane COM12. Tada į tą portą pasiunčiam laiko tekstą. Su windows darosi su keistoką komandą bat faile (yra archyve):
set /p x=%TIME% <nul >\\.\COM12
Kodėl taip keistai? Klauskit Billo. Realiai ši komanda veikia su “nestandartiniais” COM porto numeriais ir nesiunčią jokių CRLF. Gal su Linux gautusi paprasčiau. Nėra to kubiko USB įrenginys labai stabilus, todėl jei kas, darykite kaip tikri kompiuterastai: išjungiam ir įjungiam.
Aišku visi failai ir CubeMX projektas:
STM32F103 RTC OLED USB source code and hex..
P.S. vietoje super kondiko galima įdėti 3V batareiką.
Tai labai trumpa žinutė, nes ST gudručiai ir kubiko programeriai pasistengė, kad gautusi sudėtingiau. O aš poto užmiršiu jei neužrašysiu.
Kad RTC (realaus laiko laikrodis) veiktu su STM32CubeMX paketu reikia daryti taip:
Susirandam “MX_RTC_Init(void)“, skrolinam iki komentaro “USER CODE BEGIN Check_RTC_BKUP“. Ten nuskaitom vieną iš vartotojui prieinamu “backup” reikšmių ir atidarom “IF”:
/* USER CODE BEGIN Check_RTC_BKUP */
if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)
{
/* USER CODE END Check_RTC_BKUP */
Skaičius “0x5051” gali būtu bet koks, svarbu kad jis nesigautu atsitiktinai sutampantis su tikrai pilno MCU starto skaičium.
Poto paskrolinam daug kodo su RTC inicializacija…
/* USER CODE BEGIN RTC_Init 2 */
} // Kitame user code virsuje yra IF komanda. Čia ji užsidaro.
else
{
// LAIKAS BUVO ISSAUGOTAS, NES USER REGISTRAS TURI MAGIC skaiciu 0x5051
// Čia galima ką nors padaryti iš tos laimės arba pagalvoti apie kalendoriaus atstatymą. Sako kad jis nelabai
}//Čia įrašom tą MAGIC skaičių. Jis po pilno reseto ir RTC mirties turi neišlikti.
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x5051);//Write data to the specified backing area register
/* USER CODE END RTC_Init 2 */
Taip padaryta, kad useris aklai nepasitikėtu RTC veikimu ir tikrintu RAM išlikimą. Kai kuriuose forumuose rekomenduoja paprasčiausiai nutraukti RTC inicializacija su return komanda. Tačiau reikia daryti taip, kaip parašiau- pasitikrinam ar RAM išlaikė realius skaičius ir tik tada sakom, kad RTC korektiškai veikė kol procesorius stovėjo išjungtas. Jei RTC mirė, mirė ir jo RAM. Tada starto metu, žinom, kad laikrodis rodo nesamones.
P.S. Jei norim sekundinio pertraukimo, tai reikia paleisti kur nors RTC init gale šitą makrosą:
__HAL_RTC_SECOND_ENABLE_IT(&hrtc,RTC_IT_SEC);
Pratesimas- grafinių ekraniukų bibliotekos gcc C kalbos puristams. Kiek paoptimizuotos, pataisytos kelios ardruinistų ir adafruitistų klaidos. Ir aišku pridėta savų klaidų. Vienas ekraniukas I2C, visi kiti SPI. Ekraniukai naudoja tuos pačius SPI, D/C ir RESET signalus, ekraniukai pasirenka su CS signalu. Tai svabu, nes pats naujausias ekraniukas (240 x 240) neturi CS kojos išvestos į jungtį. Jungiant prie dedikuoto SPI tai nėra problema. Deja šiame projekte teko palituoti.
Ekraniukai (iš kairės į dešinę): ILI9341 (320 x 240), ST7789W (240 x 240), seniausias ST7735R (160 x 128, galimos kitos konfiguracijos), SSD1306 (128 x 64), SSD1306 (128 x 32, I2C).
Mažiesiems ekranams neparašytos grafinės bibliotekos, kaip matosi iš nuotraukos, naudojamas (vogtas) šriftas turi klaidas. Manau, vėliau pabaigsiu Windows softą šriftų redagavimui ir ekskportui, nes užkniso tie šriftai.
Bibliotekos kiek kitų versijų nei pirmame straipsnelyje, nes teko kiek unifikuoti ir optimizuoti. Pvz- jei reikia perduoti kelis baitus iš eilės, tai ir siunčiam kelis baitus, o ne kelis kartus siunčiam po baitą. Arba va:
//buvo:
for (pixels = 0; pixels < x1 - x0 ; pixels++) { ili9341_send_word(color); }
//tapo:
for(x0=x0;x0<x1;x0++){ILI9341_send_word(color);}
Pirma eilute originali, antra mano. Sutaupom kintamąjį ir bereikalingą skaičiavimą.
Dar vienas:
//buvo:
for(i=0;i < (w * h);i++)
{
c1 = *buffer++;
c2 = *buffer++;
ili9341_send_byte(c1);
ili9341_send_byte(c2);
}//tapo:
ILI9341_write_buffer(buffer, w*h*2);
Kiek teko pamakaluoti kodą, nes kažkodėl ne visur suveikė “static”, o bibliotekos taigi kartojasi. Gi niekas negamina tokio kvailo projekto su tiek skirtingų ekraniukų.
Visas source kodas ir sukompiliuoti binarai:
LCD OLED screens SPI and I2C libraries for STM32CubeMX with demo program.
Konfiguracijos pagrinde vienoje vietoje ir darosi su #define. OLED ekraniukai naudoja harwarinį skrolinimą, galima diminti, kad pamažinti burn-out.
Bet kokios naujos programos kurimas kontroleriukui tai iš esmės senesnių failų dėlionė iš bibliotekos. Todėl kiek labiau panaudojus STM32 serijos kontrolerius teko persirašyti kelias savo naudojamas bibliotekas iš AVR į STM32Cube versijas. Buvo sukurtas USB-COM projektas ir prie jo prikabinta visa serija bibiliotekų. Jos tikrai veikia ir kiek “normalizuotos”- senosios buvo istoriškai chaotiškos. Konversija praėjo keistokai lengvai. Vienas tik reikalas kuris suėdė kiek nervų- pačio STM32F čipuko jautrumas I2C šynos terminatoriams.
Visi jutikliai ir moduliukai iš Kinijos. Tik FM75 nuluptas nuo televizoriaus, o MAX44007 dovanotas žmogaus.
Veikiantys moduliai:
Pastabos: OLED ekraniukas naudoja Commodore 64 šriftą. Jį galima pakeisti kitu. Tekstinis ekraniukas- tai klasikinis LCD ekraniukas su ar be pašvietimo, paprastai jungiamas prie 7 ar daugiau GPIO pinų. Tie ekranai paprastai būna 5v technologijos ir su 3V technologija dažnai nerodo vaizdo. I2C I/O ekstenderis leidžia suderinti su 5V maitinimu- patį LCD ir IO modulį maitinam nuo 5V (tiesiai iš USB), o procesoriukas nuo 3V.
Visas kodas pilnai suderinamas su STM32CubeMX ir HAL. Kompiliuojasi su gcc be jokių warningų.
Nusikrauti source code, kubiko projektą ir sukompiliuotus failus:
STM32CubeMX project, I2C LM75 PCF8574 MAX44007 BMP180 text lcd screen
Per virtualų COM portą matosi visi jutiklių rodymai. Dalis informacijos išmetama per ekraniukus.