Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: RDa 06. 01. 2025, 18:09:27
-
Myslím, že se tady najde i několik odborníků - řeším oživení a "BSP" pro projekt odvozený od Arduino DUE desky.
TLDR: Nefunguje mi zápis do PIO výstupů paralelně, jen skrze set/clear registry. Hodiny pro perfierii jsem povolil.
Relevantní kusy kódu:
#define config_pio_out( port, bits ) \
port->PIO_PER = bits; \
port->PIO_OER = bits; \
port->PIO_PUDR = bits;
#define update_pio( port, bits, enable ) \
if (enable) { \
port->PIO_SODR = bits; \
} else { \
port->PIO_CODR = bits; \
}
/*
OCRX[8:1] = PC[27:20]
OCTX[8:1] = PD[7:0]
*/
#define OPTO_TX_DEFAULT 0x00
#define OPTO_TX_OFFS 0
#define OPTO_TX_MASK ( PIO_PD7 \
| PIO_PD6 \
| PIO_PD5 \
| PIO_PD4 \
| PIO_PD3 \
| PIO_PD2 \
| PIO_PD1 \
| PIO_PD0 )
void config_digital_out(void) {
// for ODSR to work?
PMC->PMC_PCER0 = 1 << ID_PIOD;
// classic
config_pio_out( PIOD, OPTO_TX_MASK );
update_digital_out( OPTO_TX_DEFAULT );
}
void update_digital_out( unsigned bits ) {
#if 1
PIOD->PIO_ODSR = ( PIOD->PIO_ODSR & ~(OPTO_TX_MASK) )
| ( (bits<<OPTO_TX_OFFS) & (OPTO_TX_MASK) );
#else
update_pio( PIOD, PIO_PD7, bits & BIT(7) );
update_pio( PIOD, PIO_PD6, bits & BIT(6) );
update_pio( PIOD, PIO_PD5, bits & BIT(5) );
update_pio( PIOD, PIO_PD4, bits & BIT(4) );
update_pio( PIOD, PIO_PD3, bits & BIT(3) );
update_pio( PIOD, PIO_PD2, bits & BIT(2) );
update_pio( PIOD, PIO_PD1, bits & BIT(1) );
update_pio( PIOD, PIO_PD0, bits & BIT(0) );
#endif
}
a
// ./system/CMSIS/Device/ATMEL/sam.h
#include <sam.h>
#include <libsam/include/pmc.h>
:
int main( int argc, char *argv[] ) {
/* Initilize the SAM3 system */
SystemInit();
config_digital_out();
while(1) {
static unsigned n = 0;
n = ( n + 1 ) & 0xFF;
update_digital_out( n );
}
return 0;
}
Po zmene #if 1 na #if 0 v update_digital_out(), se generuje pattern s frekvenci ktera je polovina/dvojnasobek kazdym dalsim bitem, pri pouziti ODSR se ale nic nedeje, vsechny piny jsou v nule. Mam tam nejaky preklep nekde? Nebo to co chci nejde udelat? Nebo jsem jen na neco dalsiho zapomnel? Nebo snad nejaka errata? :D
Kod pro SAM3X8E cpu jsem vzal z Arduino gitu: https://github.com/arduino/ArduinoCore-sam ale builduji si aplikaci uz mimo IDE, linkuji to skrze linker script a .a pro tu systemovou knihovnu z Arduina.
Ostatni veci funguji (jako SystemInit a pak mam i SysTick_Config a na nej navazany delay_ms, jen ten IO port ne a nevim kde je chyba - s temito mcu nedelam.
Arduino samotne nema IO primitiva na ovladani portu timto stylem, a hodiny pro periferii povoluje jen kdyz na portu je alespon jeden pin jako vstup (asi kvuli glitch filtru a prerusenim).
-
A je v ODSR očekávaná hodnota (tj. je to HW problém či konfigurace čipu) nebo se do OSDR nedostane správná hodnota (chyba v kódu) ... debugger či nějaký pomocný výpis?
Osobně bych si tipnul, že je to problém s velikostí typů a "unsigned bits" jsou 16bit na téhle architekřure a snažíš se to vyrotovat výš než 16bit, takže z toho vyjde nula? Nemám tyhle typy bez jasné velikosti rád, protože si nepamatuji, kterej překladač/architektura má jaké velikosti (navíc se to obvykle dá ovlivnit i nastavením překladače) ...
-
Tak jsem na to prisel.
ODSR je navic maskovano "W" bity, na ktere se pristupuje OWER/OWDR (pripadne cteni pres OWSR, bohuzel na primy zapis masky tam neni polozka), takze spravny kod je nakonec tento:
void update_digital_out( unsigned bits ) {
PIOD->PIO_OWDR = ~OPTO_TX_MASK;
PIOD->PIO_OWER = OPTO_TX_MASK;
PIOD->PIO_ODSR = bits << OPTO_TX_OFFS;
}
-
Hlavně že to funguje a omlouvám se za podezdření z tak základní chyby :)
-
Btw proc myslis ze unsigned jsou 16-bit? Je to 32bit arm podle vseho. Samozrejme na AVR (mega/xmega) jsem pozival o hodne explicitnejsi typovani (pres u8/u16/u32) se snahou usetrit misto i vypocetni cykly, protoze to je nativne spis 8 bit nez 16. Tyhle prechody jsou vzdy za trest.. ale holt, nas zakaznik, nas pan :D
-
Podle specifikace C musí být int aspoň 16bit, takže by teoreticky mohl, a čekal jsem nějakou zákeřnost, když v tom figurovalo něco převzatého z Arduina ...
Ale jak říkáš, typicky je int podle architektury nebo aspoň těch 16bit.