Category Archives: MCU

ARM:0018 STM32CubeMX hack – printerio klasė

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:

  • Prisijungia kaip kompo kaip USB įrenginys, nuskaito standartinius deskriptorius ir kompiuteris mato kaip printerio klasę.
  • Printeris duoda 1284 stringą į hostą, tačiau ar teisingai hostas tai interpretuoja nežinau.
  • Printeris spausdina. Tačiau veikia tik uni ir bi- directional režime. Kažkodėl 1284.4 režime mano windows pastringa.
  • Printeris nesigavo pilnai “plug ir peilis”. Jį reikia dagrūsti rankiniam režime. Mano AVR variantas buvo pilnas “plug and play”.
  • Kaip ir AVR versijoje nesugebu perduoti STATUS (baigėsi popierius, printeris “on-line/selected”) į hostą. Lygtai viską parašiau, bet windows draiveris paprasčiausiai neklausia ir ignoruoja mano bandymus.
  • “MS descriptor” teoriškai padarytas (0xEE), bet kažkodėl neveikia. Gal Windows neklausia, arba klausia taip, kad aš nepastebiu.

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ą.

ARM:0017 – Eik miegot laikrodis

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ą:
OLED RTC to limit gaming time. STM32F103c and I2C OLED USB settings
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ą.

ARM:0016 STM32CubeMX – RTC problema

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);

ARM:0015 STM32CubeMX ekraniukų bibliotekos 2 dalis

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.

SPI and I2C graphic LCD OLED modules with STM32 stm32cubemx gcc
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.

ARM:0014 STM32CubeMX jutiklių ir ekraniukų bibliotekos

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.

STM32F103 blue pill with OLED, I2c LM75 BM180 MAX44007 PCF8574
Visi jutikliai ir moduliukai iš Kinijos. Tik FM75 nuluptas nuo televizoriaus, o MAX44007 dovanotas žmogaus.
Veikiantys moduliai:

  • LM75 temperatūros jutiklis, I2C (FM75 tai rimtesnis, bet suderinamas su LM75)
  • MAX44007, I2C, apšvietimo jutiklis.
  • PCF8574, I2C, 8bit I/O extenderis.
  • Tekstinis LCD ekraniukas ant PCF8574 extenderio. Kartu gaunasi ir 5V atskirimas nuo 3V.
  • SSD1306 kontrolerio OLED ekraniukas ant I2C šynos.
  • Analoginiai signalai- nu čia ne moduliukas, bet pačio STM dalis.
  • RTC (laikrodis)- čia irgi ne moduliukas, o STM dalis.
  • BMP180 atmosferos slėgio jutiklis su temperatūros jutimu.

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.

ARM:0013 STM32CubeMX – USB HID klavietura

O dabar pasinersim į USB klavietūros gamybą. Pasinaudosim STM32CubeMX konservais, HID mouse pavyzdžiu, bet perdarysim savaip, kad gautusi klavietūra. Viską darom kaip USB-Peles pavyzdyje. Visiskai viską. Tačiau pakeisime įrenginio aprašymą (descriptor). Labai negudrausim, bet iš www.usb.org nusikrausim HID descriptorių generatorių ir jame pasirinksime klavietūra. Tai universalus ir perteklinis descriptorius, bet kol kas, paprastumo labui, naudosim taip kaip yra.

USB HID descriptor generator
Programos sugeneruotą descriptorių eksportuojam į “h” tipo failą: keybrd.h (jis bus įdėtas į source code archyvą).
Continue reading →

ARM:0012 STM32CubeMX – USB HID pele

Sekantis projektas iš konservų dėžutės vardu STM32CubeMX- pelė. Tai bus USB HID (human interface device) pelė. Pradedam nuo pelės, nes ji sugeneruojama automatiškai ir nereikia vargti su įrenginio aprašymų košmaru (device descriptor). Viską darom kai su virtualiu COM portu, tik pasirenkam kitą įrenginį:

STM32CubeMx HID mouse
HID klasė, daugiau pas kubika nieko nepakeisi (o gaila, nes norėturi didesnės klasių bibliotekos. O ir čia niekur neparašyta, kad čia ne paprastas HID, kas gali būti bet kas, o paprasčiausia pelė).
Continue reading →

ARM:0011 STM32CubeMX – pertraukimas per kojas

“Pertraukimai per kojas” :).

Iš vienos nesamonės liko tokia mažytė klavietūra su keturiais laidais. Maniau kad USB, deja ne- PS/2 standarto. Kaip tik proga parašyti ką nors apie programavimą. Todėl pirma, tarpinė užduotis: pajungti PS/2 klavietūra prie virtualaus COM porto (USB).

Amstrad mailboard
Kadangi jau męs mokam STM32CubeMX pradmenis iš senesnių postų: Pradinis ir USB COM portas, bus mažiau rašymo.
Taigis pradedam…
Continue reading →

ARM:0010 STM32CubeMX- USB 2 COM dongle

Taigis. Karantinas ir po gana daug dienų degradacijos nutariau dar kiek pasinagrinėti tą MX kubą ir pagaminti USB į serial adapterį. Taip jau gavosi, kad prigriebiau kažkada tokių PCB su STM32F102 procesoriuku. Kas tai buvo originaliai aš nežinau. Tačiau čia yra “košerinis” USB ir RS485/422 išvadas. Todėl eksperimentams kaip tik:

STM32F102 as USB to UART/COM dongle
Prigriebiau tik tiek. O buvo dešimtim. Tokiom nesulaužytom plokštėm. Per vidurį išvesti programavimo ir kitokie signalai. Ant popieriaus parašytas pinoutas. Todėl ten pajungiam STLink programatorių. O su raudonu ir žaliu laideliu uždarom serial porto kilpą. Ten diferencialinis signalas, todėl du laidai- pliusinis ir minusinis.

Taigis pradedam…
Continue reading →