Ich habe hier gerade ein Board von mir mit einem ATSAMC21E18A liegen auf
dem ich bis auf CMSIS keine fremden Libs benutze.
Das Board hat allerdings praktisch nur einen SPI Anschluss an dem gerade
ein EVE2-50G Display hängt, sowie einen CAN-FD den ich gerade nicht
benutzen kann.
Ich könnte noch per ADC und Spannungsteiler die Versorgung messen.
https://github.com/RudolphRiedel/SAMC21_one
Mit dem 16MHz Quarz da dran initialisiere ich den Takt da gerade so:
1 | void init_clock(void)
|
2 | {
|
3 | REG_NVMCTRL_CTRLB = NVMCTRL_CTRLB_RWS(2); // Set the NVM Read Wait States to 2, Since the operating frequency will be 48 MHz
|
4 |
|
5 | REG_OSCCTRL_XOSCCTRL = OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms
|
6 | OSCCTRL_XOSCCTRL_RUNSTDBY |
|
7 | OSCCTRL_XOSCCTRL_AMPGC |
|
8 | OSCCTRL_XOSCCTRL_GAIN(3) |
|
9 | OSCCTRL_XOSCCTRL_XTALEN |
|
10 | OSCCTRL_XOSCCTRL_ENABLE;
|
11 |
|
12 | while((REG_OSCCTRL_STATUS & OSCCTRL_STATUS_XOSCRDY) == 0);
|
13 |
|
14 | /* configure the PLL, source = XOSC, pre-scaler = 8, multiply by 24 -> 48MHz clock from 16MHz input */
|
15 | REG_OSCCTRL_DPLLCTRLB = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(1); // setup PLL to use XOSC input
|
16 | REG_OSCCTRL_DPLLRATIO = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(23);
|
17 | REG_OSCCTRL_DPLLCTRLA = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE;
|
18 | while((REG_OSCCTRL_DPLLSTATUS & OSCCTRL_DPLLSTATUS_CLKRDY) != 0); // wait for the pll to be ready
|
19 |
|
20 | REG_GCLK_GENCTRL0 = GCLK_GENCTRL_DIV(0) |
|
21 | GCLK_GENCTRL_RUNSTDBY |
|
22 | GCLK_GENCTRL_GENEN |
|
23 | //GCLK_GENCTRL_SRC_XOSC |
|
24 | GCLK_GENCTRL_SRC_DPLL96M |
|
25 | GCLK_GENCTRL_IDC ;
|
26 |
|
27 | while((REG_GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL0) != 0); /* wait for the synchronization between clock domain to be complete */
|
28 |
|
29 | REG_OSCCTRL_OSC48MDIV = OSCCTRL_OSC48MDIV_DIV(0); // set 48MHz Oscillator to 48MHz ouput
|
30 |
|
31 | REG_GCLK_GENCTRL1 = GCLK_GENCTRL_DIV(0) |
|
32 | GCLK_GENCTRL_RUNSTDBY |
|
33 | GCLK_GENCTRL_GENEN |
|
34 | GCLK_GENCTRL_SRC_OSC48M |
|
35 | // GCLK_GENCTRL_SRC_DPLL96M |
|
36 | GCLK_GENCTRL_IDC ;
|
37 |
|
38 | while((REG_GCLK_SYNCBUSY & GCLK_SYNCBUSY_GENCTRL1) != 0); // wait for the synchronization between clock domains is complete
|
39 | }
|
Wobei ich GLCK1 nur für einen Timer benutze mit dem ich ein schlichtes
Profiling mache.
Da ich noch ein Adafruit Trinket M0 irgendwo herumfliegen habe,
habe ich mal mit dem etwas herumgespielt:
Beitrag "Bare-Metal ATSAM"
Das Board hat nur keinen SWD, also habe ich im Arduino Framework
angesetzt um per direktem Register-Zugriff den SPI zu benutzen, im
zweiten Ansatz dann per DMA.
Hat nur irgendwie niemanden interessiert, auch wenn man Beispiele dazu
praktisch nicht finden kann.
Jetzt habe ich nur gerade keinen LA hier, sonst würde ich mir mal den
SPI am C21 im DMA ansehen wie es da mit Pausen zwischen den Bytes
aussieht.
Allerdings, Hardware-Controlled Chip-Select benutze ich schon mal nicht,
ich meine das geht gar nicht für eine größere Anzahl Bytes am Stück.
Und mit den Display könnte ich bis 4k am Stück schicken.
Mit dem E51 habe ich mich auch beschäftigt, benötigt habe ich den bisher
aber nicht wirklich und so habe ich für den zum Beispiel DMA nicht
implementiert.
Mit XMegas habe ich dabei keine Erfahrung, es gibt keine XMegas mit CAN.
Und da hier gerne sehr schnell und lautstark missioniert wird, es gibt
auch keine Automotive STM32 mit CAN-FD.