1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 |
|
6 | // Pins für SPI definieren
|
7 | #define SCK 5
|
8 | #define MOSI 7
|
9 | #define SS 4 // Als normaler Ausgang nehmen
|
10 |
|
11 | //Funktion für Port Konfiguration
|
12 | void port_init(void);
|
13 | //Funktion für USART SPI Mode Konfiguration
|
14 | void spi_init(void);
|
15 | //DMA Konfiguration
|
16 | void dma_init(void);
|
17 | //DMA Start
|
18 | void start_dma(void);
|
19 | //32Mhz clock
|
20 | void sync_osc(void);
|
21 | //Interrupt
|
22 | void interrupt_init(void);
|
23 |
|
24 |
|
25 | uint8_t Buffer[255]; //Buffer
|
26 | uint8_t i; //Hilfsvariable
|
27 |
|
28 | int main(void){
|
29 | //clock initialisieren
|
30 | sync_osc();
|
31 | //clock initialisieren
|
32 | port_init();
|
33 | //clock initialisieren
|
34 | spi_init();
|
35 | interrupt_init();
|
36 | //DMA initialisieren
|
37 | dma_init();
|
38 |
|
39 |
|
40 | //Buffer mit Daten füllen
|
41 | for (i = 0; i < 255 ; i++) {
|
42 | Buffer[i] = i;}
|
43 | start_dma();
|
44 |
|
45 |
|
46 |
|
47 | //Hauptschleife
|
48 | while(1){
|
49 |
|
50 | //USARTE1.DATA = 255;
|
51 | //while (! (USARTE1.STATUS & USART_DREIF_bm));
|
52 |
|
53 | }
|
54 | }
|
55 |
|
56 | //Port Initialisierung
|
57 | void port_init(void){
|
58 | // CS, CLK und MOSI als Ausgänge
|
59 | PORTE.DIRSET = (1 << MOSI) | (1 << SCK) | (1 << SS);
|
60 | }
|
61 |
|
62 | void spi_init(void){
|
63 | // 100Khz SPI Frequenz
|
64 | USARTE1.BAUDCTRLA = 159;
|
65 | USARTE1.BAUDCTRLB = 0;
|
66 |
|
67 | // Frameformat (MSB first), SPI Mode 0
|
68 | USARTE1.CTRLC = USART_CMODE_MSPI_gc;
|
69 |
|
70 | USARTE1.CTRLA = 0;
|
71 |
|
72 | // TX aktivieren
|
73 | USARTE1.CTRLB = USART_TXEN_bm;
|
74 | }
|
75 |
|
76 | void dma_init(void){
|
77 | //DMA aktivieren
|
78 | DMA.CTRL = DMA_CH_ENABLE_bm;
|
79 | //Modus Transaktion, increase und decrease, Burst
|
80 | DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc
|
81 | | DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc;
|
82 |
|
83 | // Trigger Source ist USARTE1 (SPI). Triggerung wenn der Datenpuffer leer ist.
|
84 | DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTE1_DRE_gc;
|
85 |
|
86 | //8Bit Quelle
|
87 | DMA.CH0.SRCADDR0 =(((uint32_t)(&Buffer))>>0*8) & 0xFF;
|
88 | DMA.CH0.SRCADDR1 =(((uint32_t)(&Buffer))>>1*8) & 0xFF;
|
89 | DMA.CH0.SRCADDR2 =(((uint32_t)(&Buffer))>>2*8) & 0xFF;
|
90 |
|
91 | //8Bit Übertragung an SPI
|
92 | DMA.CH0.DESTADDR0 = ((uint32_t) &USARTE1.DATA >>0*8)&0xFF;
|
93 | DMA.CH0.DESTADDR1 = ((uint32_t) &USARTE1.DATA >>1*8)&0xFF;
|
94 | DMA.CH0.DESTADDR2 = ((uint32_t) &USARTE1.DATA >>2*8)&0xFF;
|
95 |
|
96 | }
|
97 |
|
98 | //DMA Start
|
99 | void start_dma(void){
|
100 |
|
101 | //Datenpuffer 256
|
102 | DMA.CH0.TRFCNT = 256;
|
103 | // DMA CH0 aktivieren (Takt)
|
104 | DMA.CH0.CTRLA = DMA_CH_ENABLE_bm | DMA_CH_REPEAT_bm|DMA_CH_SINGLE_bm;
|
105 | //DMA.CH0.CTRLA = 0xA4;
|
106 | }
|
107 |
|
108 | //clock initialisieren
|
109 | void sync_osc(void) {
|
110 | /*Oscillator auf 32Mhz einstellen*/
|
111 | OSC.CTRL |= OSC_RC32MEN_bm;
|
112 | /*Wenn Oscillator stabil wird das Flag RC32MRDY
|
113 | * gesetzt und 32Mhz können benutzt werden*/
|
114 | while (!(OSC.STATUS & OSC_RC32MRDY_bm)) {};
|
115 | CCP = CCP_IOREG_gc;
|
116 | /*Clock auf 32Mhz einstellen*/
|
117 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
|
118 | /* auto kalibierung ein */
|
119 | DFLLRC32M.CTRL = DFLL_ENABLE_bm;
|
120 |
|
121 | }
|
122 |
|
123 | void interrupt_init(void){
|
124 | // Globale Interruptfreigabe
|
125 | sei();
|
126 | //Interrupts (Highlevel,Mediumlevel und Lowlevel freigeben)
|
127 | PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm;
|
128 | }
|
129 |
|
130 |
|
131 | ISR (DMA_CH0TRNFIF_vect){
|
132 | _delay_ms(200);
|
133 | start_dma();
|
134 | }
|