ARM37: zuikis ir vėžliukas

June 26th, 2022

Kas nesidomi mikroprocesorių programavimų, gali ir neskaityti. Bus nelabai įdomu… :)

Klasikinė bėda- yra du procesai, kurių veikimo greičiai labai skiriasi. Šiam variante: USB ir UART. Kaip suderinti jų bendrą veikimą? Štai imat kokį source code iš interneto platybėse publikuotos pamokėlės, viskas kaip ir veikia kol spaudžiojat duomenis iš klaviatūros, o jei pabandot “copy-paste" ir staiga tekstas pradeda nebepersiduoti, raidės prapuola ir procesoriukas pastringa. Kodėl? Todėl, kad reikia suderinti skirtingo greičio ir veikimo principo procesus:
Pirmas procesas, USB, tai paketinis duomenų perdavimas su galimybe pristabdyti duomenis ar net paprašyti juos pakartoti. Viskas vyksta gana greitai.
Antras procesas, UART, tai nuoseklus, lėtas duomenų perdavimas. Ir pats perdavimas pririštas prie laiko. Jei nenaudojam kontrolinių linijų, procesą negalime sustabdyti. Kai duomenų per daug, jie prarandami.

Taip atrodo iš žmogaus pusės, iš kontrolerio pusės tai jau keturi procesai: USB TX, USB RX, UART TX, UART RX.

Kad suvaldyti šį chaosą, reikia procesus paleisti nepriklausomai, per pertraukimus. Arba, kai siunčiam, tai galima ir pastabdyti pagrindinį ciklą (bent jau šiame eksperimente). Gaunais taip:

  1. UART RX, per pertraukima ir net DMA. Tačiau nežinom kiek baitų gausim, tai visas mūsų DMA/IRQ tvarko tik vieną baitą.
  2. UART TX, siuntimas blokuojant procesoriaus darbą. Mūsų programa nieko protingo nedaro, tai galima blokuoti.
  3. USB RX, tikriausiai per pertraukimą, naudojam HAL biblioteką.
  4. USB TX, blokuojamas ar tai IRQ, naudojam HAL biblioteką*.

Visi procesai per pertraukimą daro tik vieną darbą- jei gaunam duomenis, įrašom duomenis į buferį (jei yra vietos). Buferis vadinasi “circle" nes tai kaip ir cirkuliarinis buferis**, tik aš jo neperpildau, prarandu duomenis jei buffer overflow. O pats smagumas vyksta pagrindiniam, amžinam cikle:

 while(1)
	{
	HAL_IWDG_Refresh(&hiwdg); //watchdogas
	
	while(circle_available(&cc)>0) //ar yra duomenu gautu is UART?
		{
		i=circle_available(&cc);
		for(j=0;j<i;j++)
			{
			tmp[j]=circle_pull(&cc); //viska persikopijuojam ir issiunciam
			}
		CDC_Transmit_FS(tmp, i); //siuntimas per USB (blocking?. gal ne)
		}
	
	while(circle_available(&cu)>0) //ar yra duomenu gautu is USB?
		{
		i=circle_available(&cu);
		for(j=0;j<i;j++)
			{
			tmp[j]=circle_pull(&cu); //viska persikopijuojam ir issiunciam
			}
		send_uart((char *) tmp,i); //siunciam per UART (blocking)
		}
	}
}

Tikriausiai senas Wordpresas nenusiaubė programos teksto.

Iš principo programa veikia taip: yra ką perduoti? perduodam! ir vėl iš naujo.

Tačiau galima dar labiau viską užkomplikuoti- TX padaryti su atskirais buferiais ir siuntimo procesą irgi padaryti asinchroninį. Tada procesoriuje išsilaisvintu dar šiek tiek resursų kokiai nors pagrindinei programai.
Dar viena bėda- nenumatytas atvejis, kai trumpuose momentuose, kol ištraukiami duomenys į buferį, kas nors įrašytu naujus duomenis. Teoriškai circle buferis apsaugo nuo tokių nemalonumų… Praktiškai, buitiniams reikalams viskas veikia.

Šis straipsniukas skirtas man pačiam prisiminti, nes reikėjo ir neatsiminiau. Teko kiek parašinėti.

*) HAL USB biblioteka netikrina ar duomenys išėjo. Jei reikalingi TIKRAI gerai daryti, reikia tikrinti USB būklę. Tada jau geriau nagrinėtis ATARI disko emuliatoriaus kodą (rodos ten padariau viską)
**) circular buffer, cirkuliarinis buferis leidžia rašyti ir skaityti duomenis iš buferio. T.y duomenys kaip gyvatėlė Uroboras, nauji duomenys prisideda prie galvos, o seni nusiima prie uodegos. Viskas gerai, kol galva nepasiekia uodegos ir gyvatėlė neįsikanda. Tada prarandam duomenis.
P.S. source kodas neoptimizuotas dėl aiškesnio vaizdavimo.

ARM36: Burbuliniai LED

June 15th, 2022

Antikvarinis LED indikatorius, tikriausiai iš kokio nors tarybinio kalkuliatoriaus. Žavi savo netobulumu:

burbulinis LED
АЛС318

Simboliai mažyčiai (todėl ir plastikinės linzės), šviesumas mizernas (prie tausojančių srovių). Bet savotiškai žavingas.
Tokiam indikatoriui pajungti reikia gana daug laidų ir dinaminės indikacijos. Demonstracijai panaudojau breadboard ir “bluepill" plokštę (STM32F103C8t)- mikroschema mažoka, beveik visos kojos sunaudojamos indikatoriui. Prie anodų (pliusinių elektrodų) reikia prikabinti kokius nors rezistorius, kad apriboti srovę per LED, tik 3mA statiniam režime per vieną segmentą. Naudojant dinaminę indikaciją leistina srovė 40mA, bet jei indikacija sustos, tai atia LEDams.

STM32F103 bluepill source code (StmCubeMX) ir kompiliuotas hex.

Pajungimas: PA0-PA7 (per rezistorius) LED segmentai, PB0,PB1, PB3-PB9 - katodai (ženklų vietos).

Kad pagreitinti programos darbą, rašom visą baitą į kojeles:

uint32_t data = GPIOA -> ODR;
data &= 0xFF00;
//Bits 31:16 Reserved, must be kept at reset value.
//Bits 15:0 ODRy: Port output data (y= 0 .. 15)
//These bits can be read and written by software and can be accessed in Word mode only.

data |= font[a];
GPIOA -> ODR = data;

Taip ir biški neaišku- 32 ar 16 bitų reikia rašyti/skaityti. Išbandžiau visus variantus, visi veikia.

Kitoje vietoje:

uint32_t data = GPIOB -> ODR;
data |=0b00000000000000000000001111111011;
GPIOB -> ODR = data;

Irgi tas pats klausimas: 16 ar 32. O galima gal optimizuoti naudojant GPIOx_BSRR? (porto bitų “resetinimo/setinimo" registas)

GPIOB ->BSRR =0b00000000000000000000001111111011;

Veikia ir šis variantas.

Griozdišką:

/* 74LS154 butu geriau */
if (screen_pos==0) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);}
else if (screen_pos==1) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);}
else if (screen_pos==2) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);}
else if (screen_pos==3) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);}
else if (screen_pos==4) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);}
else if (screen_pos==5) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);}
else if (screen_pos==6) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);}
else if (screen_pos==7) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);}
else if (screen_pos==8) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);}

Irgi galima optimizuoti. Bet ar šiais laikais kas nors ką nors optimizuoja?
Gerai…. kaip toks variantas:

unsigned int bitai[]={512,256,128,64,32,16,8,2,1};
GPIOB ->BSRR =(bitai[screen_pos]<< 16);

arba:

GPIOB ->BRR =(bitai[screen_pos]);

Norint pataupyti MCU kojas, galima statyti dekodavimo mikroschemą 74LS154 (К155ИД3). Tada vietoje 9 kojų užtektu kokių 4.
red led decoder

Demonstracinė programa skaičiuoja 32 bitų kintamąjį, tai tikrai pats kairinis simbolis nepasikeis. O ir laukti kitų simbolių gali ir pabosti.

Tai tik tiek. :)

(optimizaciniai eksperimentai į archyvą neįtraukti)

Švilpiko dienos radija

June 2nd, 2022

Nu gal ne visai, originale tai Panasonic RC-6025, o pas mane Sanyo Sterocast RM5320, tikriausiai 1972 metų gamybos (gali būti ir su kitu brendu, kad ir Siemens alpha). Tikrai japoniška, nes visur tik “made in Japan", ant garsiakalbio Sanyo ir panašiai.
Sanyo sterocast
Kodėl žinau, kad yra kitu brendų? Ogi todėl, kad pirmoji radija kur pirkau buvo Siemens. Bet ji ne tik su sugadintu motoriuku (plastikinis dantratis be dantų), bet ją man dar ir stiprokai sudaužė- 70-tųjų plastikas labai trapus.
Read the rest of this entry »

Betkas su delnu ir BT

May 24th, 2022

Nėra labai laiko ką nors normaliai parašyti, tai keletas randominių fotkių:
KM
O jetau, tai “keemkės"! Rusiškas ir tarybinis paladis su platina.

koaksas
Tai kažkoks koaksalinis šakotuvas. Tikriausiai galingas.

BT
(HQ-BLE-1, HMI board)
Tai husqvarnos žoliapjovės ekrano plokštė su BT. Į BT čipą (CC2640R2) supumpavau kinišką firmwarą nuo HM-18/19 modulio. Tačiau pas kinišką modulį viena TX/RX koja ne per tą piną eina, tai teko pritaikyti laidelį ir rezistorių. Arba reikia “pačinti" firmwaro binarą.
Kas per debilizmas tas BT LE, keletas programų mobiliems telefonams yra, bet nėra jokio veikiančio softo windows kompiuteriui.

ARM35: LCD ir FSMC

May 2nd, 2022

Trumpa priešistorė: prisirinkom kažkokių PCB su STM32F103 mikroschemos ir nežinomu LCD. LCD buvo dviejų tipų, o pačios PCB irgi keletos variantų. Kai kurios su kitu STM32 BGA čipu ir ROM/RAM mikroschemom. Dar kitos PCB beveik tuščios ar pažeistos. Užtat visos turi mėlyną dantį ir visokias smulkmes.
Visokius kištukus gana lengvai išaiškinom (gerai, kad ne visos PCB padengtos laku), kai kurie primityvai kaip LCD pasvietimas (ar dar kieno) eina per tranzistorius, tai irgi lengvai atsibūrė. Bet liko LCD. LCD tikrai dviejų tipų- mažesnis, išjungtas juodas ir didesnis, baltas. Abu ekranai grafiniai, nes yra originali firmwarė, kur parašo kad “atnaujink softą". Pirminis softas lygtai ir universalus abiem plokštėm ir jame aptikom, kad plokštės iš Husqvarnos automatinių žoliapjovių.
Deja informacijos apie LCD ekranus ar kontrolerius nebuvo visiškai. Todėl ėmiau iš eilės visokius LCD ekranus su panašiu kiekiu pinų ir bandžiau… Pagal įtampas, pagal originalios firmwarės siunčiamus signalus atrinkau, kur maždaug duomenys, kur WR ar panašūs signalai.
Mažesnis LCD labai panašu į ST7565 ir ten viskas maždaug buvo aišku. Didelis LCD visiškai neaiškus.
Dar pasirodė labai keista, kodėl pasirinktas toks keistas pajungimas prie MCU:

PD0=D2
PD1=D3
PD4=RD
PD5=WR
PD7=CS1
PD14=D0
PD15=D1
PE3=A0
PE7=D4
PE8=D5
PE9=D6
PE10=D7

Tačiau pernelyg nesivarginau. Nes svarbiau buvo LCD. Su didesniu LCD buvo bėdos- labai panašus LCD yra UltraChip serijos kontroleriai kaip UC1610 ar UC1611. Tačiau komandos nevisos veikia. Bėda tame, kad daug komandų bendros visos serijos čipams (ar net kito gamintojo čipams), kitos komandos ignoruojamos ar panašiai. Ir dar nustebino pačio LCD ekrano pilkumo atspalvių bitų seka. Net vienu metu kilo mintis, kad ten spalvoto ekrano kontroleris pritvirtintas prie juodai-balto LCD ekrano. Dar kilo mintis, kad neteisingai nurašiau pinoutą (tikrai ne, žr. toliau).
Bežaidžiant su bitais, buvo kaip ir parašytas šioks toks softas ekrano valdymui. Tačiau norint paišyti vaizdą ant ekrano pagal pikselius, reikia nuskaityti informaciją iš ekrano. Tai galima padaryti ir “bit bang" režimu ir su STM32F103 tai vyksta gana greitai. Bet vistiek viskas labai kvaila. Buvo pasiskaitytos instrukcijos, paguglinta ir pasinagrinėtas STMkubikas ir pasirodo man nežinomas FSMC režimas, kur kaikurios MCU kojos pavirsta DATA, ADR ir kontroliniais (WE, CS ir pan) signalais. Tada skaitymas iš LCD ar rašymas į LCD (ar į kokį SRAM) pavirsta paprasta operacija- “rašymas ir skaitymas iš RAM":

*(__IO unsigned char *)(LCD_DAT_ADDR)=d;
d=*(__IO unsigned char *)(LCD_DAT_ADDR);

Ir mūsų LCD būtent ir pajungtas kaip FSMC įrenginys (dėl to ir toks keistas LCD pinouto pajungimas).
Tačiau net dvi dienas man niekas neveikė. Nes dokumentacijoje gana miglotai parašyta ir iš pirmo žvilgsnio viskas labai nelogiška. Bėda susijusi su duomenų šynos pločių ir adresu. LCD ekrano A0 pinas, kuris atskiria duomenis nuo komandų prikabintas prie A19 pino. Šio pino lygį turi reguliuoti adresu bitai:

//Musu LCD A0 pajungtas prie A19 pino.
#define LCD_CMD_ADDR 0×60000000
#define LCD_DAT_ADDR 0×60080000

Tačiau niekas neveikė. Pasirodo, mano pavyzdiniam softe buvo ne “unsigned char", o “unsigned int" (aka uint16). Kituose pavyzdžiuose net 32 bitų kintamasis. Ir dar baisiau- net keletas straipsnių rašė, kad jei naudojam 16 bitų nuskaitymą, adresas pasislenka per vieną bitą, jei 32 bitus, per du bitus. Tačiau ir tai nepadėjo, nes mano pagrindinė klaida buvo tokia, kad nuskaičius 16 bitų iš 8 pin porto, maniau, kad mažesnieji bitai turės reikalingą informaciją. Pasirodo, kad ne. Kiek suprantu, STM čipas hardwariniam lygyje prisiderina prie “bus width" ir dar net kelis nuskaitymus ar rašymus. O jei sukonfiguruota nelogiškai, viskas ir nelogiškai veikia.
Todėl, jei reikia nuskaityti BAITĄ iš 8 laidų šynos, tai reikia C kalboje ir skaityti BAITĄ. Dar nesu tikras ar skaitant WORD iš BYTE nedaromas dvigubas nuskaitymas. Šitą reikia dar patikrinti, nes LCD ekranos softas dar kiek optimizuotusi. O dėl adreso, čia man irgi kiek neaišku, bet baitų, wordų ir longwordų adresai yra atitinkamai pasislinkę, jei norime juos nuskaityti. Pas ARM gal nėra tos bėdos kur yra pas MC68000, kur negalima skaityti pabaičiui ar panašiai iš nelyginių adresų…
Labai daug ir neaiškiai parašiau, bet čia mano “brain dump" ir ši informacija skirta man prisiminti, kaip pajungti FSMC režimą pas STM32F103. Ką dar gero duoda tas FSMC? Ogi DMA.

Kad straipsnis gautusi indomesnis, va fotkė:
LCD

Tai tas didysis ekranas, deja neįjungtas pašvietimas. Naudojamas keistokas “klasikinis" TI99 šriftas kuris gal netinkamas šiam ekranui.

Ir net trys variantai source code su viskuo: mažas ekranas bitbang, didelis ekranas bitbang ir didelis ekranas FSMC:
Husqvarna LCD ir STM32F103 FSMC.

Visas source tikrai neaptvarkyti, yra labai daug eksperimentavimo ir “reverse engineering" likučių.

Purple pill arba biruolių plokštė

April 23rd, 2022

Pamenat, rašiau apie biruolius. Apie kalną STM32F103VBT čipų su kiek palenktom kojom? Tai va, pasidariau eksperimentinę plokštę. Išvedžiau VISAS kojas į 0.1″ kištukus. Dar biški RS485/CAN prielipų pripaišiau tuščioje vietoje.

Purple pill STM32F103VBT
Tikrai sunku prilituoti mikroshemą, kai kojos biški palankstytos. Bet va iš antro karto lygtai ir gavosi. Diagnostinis softas rodo, kad per visas kojytes eina signalai ir trumpų jungimų nėra. Aišku minimalus kiekis detalių ir maitinimas iš “serial debug" lizdo.
Beja, jei netyčia užblokuosit tą “serial wire", tai nedidelė bėda, užtrumpinat “Reset", pradeda programuoti ir atjungiat “Reset".

Užrašai “AL", “AH", “EL" ir panašiai, tai pinų grupės. Pvz. AL - PA(0-7), “low" dalis. AH tai PA(8-15) ir t.t.

Visi failai:
Diagnostine firmwarė - source code, STM32Cube failas, kompiliuotas HEX.
Gerberiai - Standartiniai gerberiai, jei staiga užeis noras užsisakyti PCB.
Schema - Šios plokštės schema. Gana negražiai nupaišyta (pdf).
PCB iliustracijos - Šios plokštės PCB vaizdai (pdf).
BOM.

Dėmesio, PCB, bottom pusėje jumperis SJ1 yra jau užtrumpintas į GND. T.y. BOOT0=GND. Jei reikia kitos reikšmės, reikia nupjauti pačiam jumperyje esantį takelį ir prilituoti atitinkamą rezistorių.

Visko po biški

April 16th, 2022

Nėra jokių įdomių projektų, tai bus nedidelė galerija ir bambesiai.

Jau ne kartą bambėjau apie tai:
junk
Kažkoks industrinis “čileris". Rodos jau stipriai įžengėm į 21 amžių, bet industriniai kontroleriai pribaigia savo tupizmu. Ką norėjo pasakyti šiuo pranešimu? Ogi, “generic alarm number 1″, nuo kurio viskas užblokuojama. “no" reiškia, kad aliarmas nerezetuojamas. Kas sukelia šį aliarmą? Ogi nesvarbu. Taip suprograminta.
Išsiaiškinau iki galo ir paaiškinsiu jums visą pizdėcą. Iškarto sakau, nepirkit prietaisų iš Italų.
Yra nedidelė indukcinė krosnis ir prie jos vandens šaldytuvas. Jis užpildytas ne vandeniu, bet antifryzu, nes Lietuvoje būna žiema. Jei sistema įjungta non stop, viskas buvo gerai. Bet kurį laiką nereikėjo krosnies ir kad taupyti elektrą, viskas buvo išjungta. Įjungus- klaida ir niekas neveikia. Pasirodo, debilai Italai (jie buvo įspėti dėl Lietuvos sąlygų ir antifryzo), tai suprogramino sistemą, kad jei temperatūra žemiau 10 šilumos, suveikia aliarmas (tipo išpilkit vandenį, nes netikėta žiema Palerme) ir užblokuoja cirkuliacinį siurblį (ir čilerį). Lydimo krosnis nemato cirkuliacijos ir neįsijungia. Lygiai taip pat, pats čileris, kuris turi pašildymo sistemą, nejungia jos, nes cirkuliacija užblokuota. Vienintelė išeitis- laukti pavasario, kol antifryzas pakils iki kokių 12 laipsnių. Tada viskas veiks. Jei būtų cirkuliacija, lydimo krosnis per minutę sušildytu sistemą. O jei neišjungi sistemos, tai pats čileris pašildo vandenį (antifryza). Ir aišku visur uždėti slaptažodžiai ir pats kontroleris debilnas. Kol kas nepavyko ji perprogramuoti, liko tik “tarybinis hack"- pajungti rubylnyką, kuris overraidins cirkuliacinį siurblį. ble.
Read the rest of this entry »

Čipų sakot trūkumas?

March 25th, 2022

Vienas geras žmogus pranešė, kad atvežė biruolių. Bet kažkaip nebuvo laiko- darbai prispaudė. Po kelių dienų nuėjau ir pamačiau likučius….

stm32f103
Net širdelę užspaudė…

stm32f103
STM32F103VBT6: Medium-density performance line ARM ® -based 32-bit MCU with 128 KB Flash, USB, CAN, 7 timers, 2 ADCs, 9 com. interfaces. 20KB RAM.

Čia biruoliai, matosi, kad kojelės biški kreivos. Dabar reikia projektuoti universalią PCB. Jei kam reikia, galiu semtelėti. Tikiuosi geri ir nepadirbti.

Keista lemputė

March 19th, 2022

Papuolė į rankas keistoka lemputė:
lempa
Tik du kontaktai. Pagal dizainą- panašu į foto ar kokių nors dalelių detektorių.
Read the rest of this entry »

Epochinis kiemo įvykis

March 5th, 2022

Išvažiuoji biški į fazendą, o kai parsirandi namie, pastebi kraštovaizdžio pokyčius. Neveltui tie įtartini diedai sukosi aplinkui. Kodėl šeštadienį?
stulpo nebera Kaune

Tai buvo “stalino vargonų" arba trukdymo stoties (Objekto Nr. 603) viena iš išlikusių antenų. Ji jau kurį laiką buvo nenaudojama, nes mobiliakų technologijos pasikeitė, o toks brangus žemės lopinėlis Kauno “turčių" rajone tikrai viliojo visokius biznierius. Nors žemės sklypai buvo “išdalinti nusipelniusiems žmonėms" dar prieš daugybę metų, mano nuomone čia buvo padaryta klaida. Žemes aišku “garbingi žmonės" pardavė ir kai neliko stulpo tuoj pavarys daugiabučių rajonuką.
Geriau čia buvo įrengti parką- juolab, kad čia išliko gražūs ąžuolai su žemom ir plačiom šakom- gi teritorija išbuvo daugybę metų be žmonių veiklos. Čia buvo prūdas, gyveno antys, medžiuose veisėsi pelėdos… Sklypas buvo unikalus, nes jo nereikėjo niekam grąžinti, nei palikuoniams, nei šventiems žydų kaulams. Tiesiog gabalas valstybinės žemės. Deja, bizniukas buvo prasuktas seniai.
Read the rest of this entry »

Unhappy Tikbalang